diff options
Diffstat (limited to 'common/object/src/lib.rs')
| -rw-r--r-- | common/object/src/lib.rs | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs index bb21942..7c97bee 100644 --- a/common/object/src/lib.rs +++ b/common/object/src/lib.rs @@ -12,14 +12,17 @@ mod registry; mod tests; mod value; pub use buffer::*; +use bytemuck::NoUninit; pub use registry::*; pub use value::*; use std::marker::PhantomData; #[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(NoUninit, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Tag(pub u32); + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct TypedTag<T>(pub Tag, pub PhantomData<T>); #[derive(Debug, Clone, Copy)] @@ -94,12 +97,19 @@ impl<'a> Object<'a> { pub fn get<'b: 'a, T: Value<'b>>(&'b self, tag: TypedTag<T>) -> Option<T> { self.get_typed(self.find_field(tag.0)?) } - pub fn keys<'b: 'a>(&'b self) -> ObjectIter<'b> { - ObjectIter { + pub fn keys<'b: 'a>(&'b self) -> KeysIter<'b> { + KeysIter { object: self, index: 0, } } + pub fn entries<'b: 'a, T>(&'b self) -> EntriesIter<'b, T> { + EntriesIter { + object: self, + index: 0, + ty: PhantomData, + } + } pub fn iter<'b: 'a, T>(&'b self, tag: TypedTag<T>) -> FieldIter<'b, T> { FieldIter { object: self, @@ -161,11 +171,11 @@ impl<'a> Object<'a> { } } -pub struct ObjectIter<'a> { +pub struct KeysIter<'a> { object: &'a Object<'a>, index: usize, } -impl Iterator for ObjectIter<'_> { +impl Iterator for KeysIter<'_> { type Item = Tag; fn next(&mut self) -> Option<Self::Item> { if self.index >= self.object.tags.len() { @@ -177,6 +187,25 @@ impl Iterator for ObjectIter<'_> { } } +pub struct EntriesIter<'a, T> { + object: &'a Object<'a>, + index: usize, + ty: PhantomData<T>, +} +impl<'a, T: Value<'a>> Iterator for EntriesIter<'a, T> { + type Item = (Tag, T); + fn next(&mut self) -> Option<Self::Item> { + if self.index >= self.object.tags.len() { + return None; + } else { + let value = self.object.get_typed(self.index)?; //? This ends the iterator early if there is any invalid field + let tag = self.object.tags[self.index]; + self.index += 1; + Some((Tag(tag), value)) + } + } +} + pub struct FieldIter<'a, T> { object: &'a Object<'a>, index: usize, |