diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-19 18:17:32 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-19 18:17:32 +0100 |
| commit | 3a81f654a9f49649fb6755b6e35649f0102a9572 (patch) | |
| tree | 3b6be37eac969fea2b6dee0b718cc77efe2230a8 /common/object | |
| parent | 962309ddcb033e0032258d6badebb90415a34e3d (diff) | |
| download | jellything-3a81f654a9f49649fb6755b6e35649f0102a9572.tar jellything-3a81f654a9f49649fb6755b6e35649f0102a9572.tar.bz2 jellything-3a81f654a9f49649fb6755b6e35649f0102a9572.tar.zst | |
all idents as string; move value type; add cow to queries
Diffstat (limited to 'common/object')
| -rw-r--r-- | common/object/src/lib.rs | 12 | ||||
| -rw-r--r-- | common/object/src/value.rs | 62 |
2 files changed, 58 insertions, 16 deletions
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs index 7d0c203..3e60d58 100644 --- a/common/object/src/lib.rs +++ b/common/object/src/lib.rs @@ -154,14 +154,14 @@ impl<'a> Object<'a> { Some(&values_u8[start as usize..end as usize]) } #[inline] - pub fn get_typed<T: Value<'a>>(&self, index: usize) -> Option<T> { + pub fn get_typed<T: ValueLoad<'a>>(&self, index: usize) -> Option<T> { if T::ALIGNED { T::load_aligned(self.get_aligned(index)?) } else { T::load_unaligned(self.get_unaligned(index)?) } } - pub fn get<T: Value<'a>>(&self, tag: TypedTag<T>) -> Option<T> { + pub fn get<T: ValueLoad<'a>>(&self, tag: TypedTag<T>) -> Option<T> { self.get_typed(self.find_field(tag.0)?) } pub fn keys(&self) -> KeysIter<'a> { @@ -186,7 +186,7 @@ impl<'a> Object<'a> { } } #[must_use] - pub fn extend<T: Value<'a> + Eq + Ord>( + pub fn extend<T: ValueLoad<'a> + Eq + Ord>( &self, tag: TypedTag<T>, values: impl IntoIterator<Item = T>, @@ -318,13 +318,13 @@ pub struct EntriesIter<'a, T> { index: usize, ty: PhantomData<T>, } -impl<'a, T: Value<'a>> Iterator for EntriesIter<'a, T> { +impl<'a, T: ValueLoad<'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 value = self.object.get_typed(self.index)?; let tag = self.object.tags[self.index]; self.index += 1; Some((Tag(tag), value)) @@ -338,7 +338,7 @@ pub struct FieldIter<'a, T> { tag: u32, ty: PhantomData<T>, } -impl<'a, T: Value<'a>> Iterator for FieldIter<'a, T> { +impl<'a, T: ValueLoad<'a>> Iterator for FieldIter<'a, T> { type Item = T; fn next(&mut self) -> Option<Self::Item> { if self.index >= self.object.tags.len() { diff --git a/common/object/src/value.rs b/common/object/src/value.rs index 01b0903..3db7e7c 100644 --- a/common/object/src/value.rs +++ b/common/object/src/value.rs @@ -5,8 +5,9 @@ */ use crate::{Object, ObjectBuffer, Tag}; +use std::borrow::Cow; -pub trait Value<'a>: ValueStore + Sized { +pub trait ValueLoad<'a>: ValueStore + Sized { const ALIGNED: bool; fn load_aligned(buf: &'a [u32]) -> Option<Self> { let _ = buf; @@ -53,13 +54,54 @@ impl ValueType { } } +#[derive(Debug, Clone)] +pub enum Value<'a> { + Tag(Tag), + U32(u32), + U64(u64), + I64(i64), + String(Cow<'a, str>), + Binary(Cow<'a, [u8]>), +} + +impl<'a> From<&'a str> for Value<'a> { + fn from(value: &'a str) -> Self { + Self::String(value.into()) + } +} +impl From<String> for Value<'static> { + fn from(value: String) -> Self { + Self::String(value.into()) + } +} +impl From<u32> for Value<'static> { + fn from(value: u32) -> Self { + Self::U32(value) + } +} +impl From<u64> for Value<'static> { + fn from(value: u64) -> Self { + Self::U64(value) + } +} +impl From<i64> for Value<'static> { + fn from(value: i64) -> Self { + Self::I64(value) + } +} +impl From<Tag> for Value<'static> { + fn from(value: Tag) -> Self { + Self::Tag(value) + } +} + pub trait ValueStore { fn get_type(&self) -> ValueType; fn store_aligned(&self, _buf: &mut Vec<u32>) {} fn store_unaligned(&self, _buf: &mut Vec<u8>) {} fn size(&self) -> usize; } -impl<'a> Value<'a> for &'a str { +impl<'a> ValueLoad<'a> for &'a str { const ALIGNED: bool = false; fn load_unaligned(buf: &'a [u8]) -> Option<Self> { str::from_utf8(buf).ok() @@ -76,7 +118,7 @@ impl ValueStore for &str { self.len() } } -impl Value<'_> for u32 { +impl ValueLoad<'_> for u32 { const ALIGNED: bool = true; fn load_aligned(buf: &[u32]) -> Option<Self> { buf.get(0).copied().map(u32::from_be) @@ -93,7 +135,7 @@ impl ValueStore for u32 { 4 } } -impl Value<'_> for Tag { +impl ValueLoad<'_> for Tag { const ALIGNED: bool = true; fn load_aligned(buf: &[u32]) -> Option<Self> { buf.get(0).copied().map(u32::from_be).map(Tag) @@ -110,7 +152,7 @@ impl ValueStore for Tag { 4 } } -impl Value<'_> for u64 { +impl ValueLoad<'_> for u64 { const ALIGNED: bool = true; fn load_aligned(buf: &[u32]) -> Option<Self> { let hi = u32::from_be(*buf.get(0)?) as u64; @@ -130,7 +172,7 @@ impl ValueStore for u64 { 8 } } -impl Value<'_> for f64 { +impl ValueLoad<'_> for f64 { const ALIGNED: bool = true; fn load_aligned(buf: &[u32]) -> Option<Self> { if buf.len() < 2 { @@ -156,7 +198,7 @@ impl ValueStore for f64 { 8 } } -impl Value<'_> for i64 { +impl ValueLoad<'_> for i64 { const ALIGNED: bool = true; fn load_aligned(buf: &[u32]) -> Option<Self> { u64::load_aligned(buf).map(|x| x as i64) @@ -173,7 +215,7 @@ impl ValueStore for i64 { 8 } } -impl<'a> Value<'a> for Object<'a> { +impl<'a> ValueLoad<'a> for Object<'a> { const ALIGNED: bool = true; fn load_aligned(buf: &'a [u32]) -> Option<Self> { Self::load(buf) @@ -204,7 +246,7 @@ impl ValueStore for ObjectBuffer { self.0.len() * 4 } } -impl<'a> Value<'a> for &'a [u8] { +impl<'a> ValueLoad<'a> for &'a [u8] { const ALIGNED: bool = false; fn load_unaligned(buf: &'a [u8]) -> Option<Self> { Some(buf) @@ -221,7 +263,7 @@ impl ValueStore for &[u8] { self.len() } } -impl<'a> Value<'a> for () { +impl<'a> ValueLoad<'a> for () { const ALIGNED: bool = true; fn load_aligned(_buf: &'a [u32]) -> Option<Self> { Some(()) |