aboutsummaryrefslogtreecommitdiff
path: root/common/object
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-19 18:17:32 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-19 18:17:32 +0100
commit3a81f654a9f49649fb6755b6e35649f0102a9572 (patch)
tree3b6be37eac969fea2b6dee0b718cc77efe2230a8 /common/object
parent962309ddcb033e0032258d6badebb90415a34e3d (diff)
downloadjellything-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.rs12
-rw-r--r--common/object/src/value.rs62
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(())