aboutsummaryrefslogtreecommitdiff
path: root/common/object/src/value.rs
diff options
context:
space:
mode:
Diffstat (limited to 'common/object/src/value.rs')
-rw-r--r--common/object/src/value.rs73
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>()
+ }
+}