diff options
Diffstat (limited to 'common/object/src/value.rs')
| -rw-r--r-- | common/object/src/value.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/common/object/src/value.rs b/common/object/src/value.rs new file mode 100644 index 0000000..18aae97 --- /dev/null +++ b/common/object/src/value.rs @@ -0,0 +1,73 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ + +use crate::Object; + +pub trait Value<'a>: Sized { + const ALIGNED: bool; + fn load_aligned(buf: &'a [u32]) -> Option<Self> { + let _ = buf; + None + } + fn load_unaligned(buf: &'a [u8]) -> Option<Self> { + let _ = buf; + None + } + fn store(&self, buf: &mut Vec<u8>); + fn size(&self) -> usize; +} +impl<'a> Value<'a> for &'a str { + const ALIGNED: bool = false; + fn load_unaligned(buf: &'a [u8]) -> Option<Self> { + str::from_utf8(buf).ok() + } + fn store(&self, buf: &mut Vec<u8>) { + buf.extend(self.as_bytes()); + } + fn size(&self) -> usize { + self.len() + } +} +impl Value<'_> for u32 { + const ALIGNED: bool = false; + fn load_aligned(buf: &[u32]) -> Option<Self> { + buf.get(0).copied() + } + fn store(&self, buf: &mut Vec<u8>) { + buf.extend(self.to_ne_bytes()); + } + fn size(&self) -> usize { + 4 + } +} +impl Value<'_> for u64 { + const ALIGNED: bool = false; + fn load_aligned(buf: &[u32]) -> Option<Self> { + let hi = *buf.get(0)? as u64; + let lo = *buf.get(1)? as u64; + Some(hi << 32 | lo) + } + fn store(&self, buf: &mut Vec<u8>) { + buf.extend(self.to_ne_bytes()); + } + fn size(&self) -> usize { + 8 + } +} +impl<'a> Value<'a> for Object<'a> { + const ALIGNED: bool = true; + fn load_aligned(buf: &'a [u32]) -> Option<Self> { + Self::load(buf) + } + fn store(&self, buf: &mut Vec<u8>) { + buf.extend(self.tags.iter().copied().map(u32::to_ne_bytes).flatten()); + buf.extend(self.offsets.iter().copied().map(u32::to_ne_bytes).flatten()); + buf.extend(self.values.iter().copied().map(u32::to_ne_bytes).flatten()); + } + fn size(&self) -> usize { + (self.tags.len() + self.offsets.len() + self.values.len()) * size_of::<u32>() + } +} |