use core::hash::{Hash, Hasher};
use crate::{
binding_model::{self},
FastIndexMap,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Origin {
Pool,
Derived,
}
#[derive(Debug, Default, Clone, Eq)]
pub struct EntryMap {
inner: FastIndexMap<u32, wgt::BindGroupLayoutEntry>,
sorted: bool,
}
impl PartialEq for EntryMap {
fn eq(&self, other: &Self) -> bool {
self.assert_sorted();
other.assert_sorted();
self.inner == other.inner
}
}
impl Hash for EntryMap {
fn hash<H: Hasher>(&self, state: &mut H) {
self.assert_sorted();
for entry in self.inner.values() {
entry.hash(state);
}
}
}
impl EntryMap {
fn assert_sorted(&self) {
assert!(self.sorted);
}
pub fn from_entries(
entries: &[wgt::BindGroupLayoutEntry],
) -> Result<Self, binding_model::CreateBindGroupLayoutError> {
let mut inner = FastIndexMap::with_capacity_and_hasher(entries.len(), Default::default());
for entry in entries {
if inner.insert(entry.binding, *entry).is_some() {
return Err(binding_model::CreateBindGroupLayoutError::ConflictBinding(
entry.binding,
));
}
}
inner.sort_unstable_keys();
Ok(Self {
inner,
sorted: true,
})
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn get(&self, binding: u32) -> Option<&wgt::BindGroupLayoutEntry> {
self.inner.get(&binding)
}
pub fn indices(&self) -> impl ExactSizeIterator<Item = u32> + '_ {
self.inner.keys().copied()
}
pub fn values(&self) -> impl ExactSizeIterator<Item = &wgt::BindGroupLayoutEntry> + '_ {
self.inner.values()
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = (&u32, &wgt::BindGroupLayoutEntry)> + '_ {
self.inner.iter()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn contains_key(&self, key: u32) -> bool {
self.inner.contains_key(&key)
}
pub fn entry(&mut self, key: u32) -> indexmap::map::Entry<'_, u32, wgt::BindGroupLayoutEntry> {
self.sorted = false;
self.inner.entry(key)
}
pub fn sort(&mut self) {
self.inner.sort_unstable_keys();
self.sorted = true;
}
}