aboutsummaryrefslogtreecommitdiff
path: root/common/object/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-06 19:10:37 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-06 19:10:37 +0100
commitffa6b5c4ae2cdd3e07426ed0330f3f66e90ee57b (patch)
tree79a03bc7ed938a3698ece0878f0ce5337ff6db23 /common/object/src
parentffbdb9ce397a6408d5a91cbdcbaf4e13b0c3ba0b (diff)
downloadjellything-ffa6b5c4ae2cdd3e07426ed0330f3f66e90ee57b.tar
jellything-ffa6b5c4ae2cdd3e07426ed0330f3f66e90ee57b.tar.bz2
jellything-ffa6b5c4ae2cdd3e07426ed0330f3f66e90ee57b.tar.zst
tag registry
Diffstat (limited to 'common/object/src')
-rw-r--r--common/object/src/buffer.rs12
-rw-r--r--common/object/src/lib.rs5
-rw-r--r--common/object/src/registry.rs27
-rw-r--r--common/object/src/tests.rs12
-rw-r--r--common/object/src/value.rs34
5 files changed, 89 insertions, 1 deletions
diff --git a/common/object/src/buffer.rs b/common/object/src/buffer.rs
index 56b8caf..dbde833 100644
--- a/common/object/src/buffer.rs
+++ b/common/object/src/buffer.rs
@@ -5,6 +5,7 @@
*/
use crate::{Object, Tag, ValueStore};
+use bytemuck::try_cast_vec;
pub struct ObjectBuffer(pub Vec<u32>);
@@ -48,3 +49,14 @@ impl ObjectBuffer {
)
}
}
+
+impl From<Vec<u8>> for ObjectBuffer {
+ fn from(value: Vec<u8>) -> Self {
+ ObjectBuffer(try_cast_vec(value).unwrap_or_else(|(_, v)| {
+ v.into_iter()
+ .array_chunks()
+ .map(u32::from_ne_bytes)
+ .collect()
+ }))
+ }
+}
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs
index 831dee7..522b6c1 100644
--- a/common/object/src/lib.rs
+++ b/common/object/src/lib.rs
@@ -3,12 +3,15 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
+#![feature(iter_array_chunks)]
mod buffer;
+mod registry;
#[cfg(test)]
mod tests;
mod value;
pub use buffer::*;
+pub use registry::*;
pub use value::*;
use std::marker::PhantomData;
@@ -18,7 +21,7 @@ use std::marker::PhantomData;
pub struct Tag(pub u32);
pub struct TypedTag<T>(pub Tag, pub PhantomData<T>);
-#[derive(Debug)]
+#[derive(Debug, Clone, Copy)]
pub struct Object<'a> {
tags: &'a [u32],
offsets: &'a [u32],
diff --git a/common/object/src/registry.rs b/common/object/src/registry.rs
new file mode 100644
index 0000000..7148efd
--- /dev/null
+++ b/common/object/src/registry.rs
@@ -0,0 +1,27 @@
+/*
+ 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) 2026 metamuffin <metamuffin.org>
+*/
+
+use crate::Tag;
+use log::error;
+use std::{any::TypeId, collections::BTreeMap};
+
+#[derive(Default)]
+pub struct Registry {
+ tags: BTreeMap<Tag, TagInfo>,
+}
+impl Registry {
+ pub fn add(&mut self, tag: Tag, info: TagInfo) {
+ if let Some(other) = self.tags.get(&tag) {
+ error!("Tag conflict: {:?} vs {:?}", info.name, other.name)
+ }
+ self.tags.insert(tag, info);
+ }
+}
+
+pub struct TagInfo {
+ pub name: &'static str,
+ pub r#type: Option<TypeId>,
+}
diff --git a/common/object/src/tests.rs b/common/object/src/tests.rs
index 35a29ba..143782c 100644
--- a/common/object/src/tests.rs
+++ b/common/object/src/tests.rs
@@ -37,3 +37,15 @@ fn read_multi_field() {
assert_eq!(friends.next(), Some("Charlie"));
assert_eq!(friends.next(), None);
}
+
+#[test]
+fn vec_align_test() {
+ let mut c = 0;
+ for _ in 0..10_000 {
+ let x = Vec::<u8>::with_capacity(16);
+ if x.as_ptr().align_offset(4) == 0 {
+ c += 1;
+ }
+ }
+ assert_eq!(c, 10_000, "correctly aligned vecs by system allocator")
+}
diff --git a/common/object/src/value.rs b/common/object/src/value.rs
index d77d53a..1b24e79 100644
--- a/common/object/src/value.rs
+++ b/common/object/src/value.rs
@@ -107,3 +107,37 @@ impl ValueStore for ObjectBuffer {
self.0.len() * 4
}
}
+impl<'a> Value<'a> for &'a [u8] {
+ const ALIGNED: bool = false;
+ fn load_unaligned(buf: &'a [u8]) -> Option<Self> {
+ Some(buf)
+ }
+}
+impl ValueStore for &[u8] {
+ fn is_aligned(&self) -> bool {
+ false
+ }
+ fn store_unaligned(&self, buf: &mut Vec<u8>) {
+ buf.extend(*self);
+ }
+ fn size(&self) -> usize {
+ self.len()
+ }
+}
+impl<'a> Value<'a> for &'a [u32] {
+ const ALIGNED: bool = true;
+ fn load_aligned(buf: &'a [u32]) -> Option<Self> {
+ Some(buf)
+ }
+}
+impl ValueStore for &[u32] {
+ fn is_aligned(&self) -> bool {
+ true
+ }
+ fn store_aligned(&self, buf: &mut Vec<u32>) {
+ buf.extend(*self);
+ }
+ fn size(&self) -> usize {
+ self.len() * 4
+ }
+}