aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Cargo.toml1
-rw-r--r--common/object/src/lib.rs55
-rw-r--r--common/object/src/value.rs73
-rw-r--r--common/src/lib.rs44
4 files changed, 100 insertions, 73 deletions
diff --git a/common/Cargo.toml b/common/Cargo.toml
index 51e2208..b0ecc02 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -9,4 +9,5 @@ chrono = { version = "0.4.42", features = ["serde"] }
blake3 = "1.8.2"
hex = "0.4.3"
jellystream-types = { path = "../stream/types" }
+jellyobject = { path = "object" }
base64 = "0.22.1"
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs
index 33d38d1..90ddef5 100644
--- a/common/object/src/lib.rs
+++ b/common/object/src/lib.rs
@@ -4,6 +4,9 @@
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
+mod value;
+pub use value::*;
+
use std::marker::PhantomData;
#[repr(transparent)]
@@ -78,55 +81,3 @@ impl<'a> Object<'a> {
}
}
}
-
-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
- }
-}
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>()
+ }
+}
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 769cfe2..209aeef 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -53,33 +53,35 @@ pub enum NodeIDOrSlug {
Slug(String),
}
+use jellyobject::{Object, Tag, TypedTag};
+use std::marker::PhantomData;
macro_rules! keys {
- ($($id:ident = $tag:literal $name:literal;)*) => {
- $(const $id: Tag = Tag($tag);)*
+ ($($id:ident: $type:ty = $tag:literal $name:literal;)*) => {
+ $(pub const $id: TypedTag<$type> = TypedTag(Tag($tag), PhantomData);)*
};
}
keys! {
- N_KIND = 1 "kind";
- N_TITLE = 2 "title";
- N_PARENT = 3 "parent";
- N_TAGLINE = 4 "tagline";
- N_DESCRIPTION = 5 "description";
- N_RELEASEDATE = 6 "releasedate";
- N_INDEX = 7 "index";
- N_SEASON_INDEX = 8 "season_index";
- N_MEDIA = 9 "media";
- N_TAG = 10 "tag";
- N_RATINGS = 11 "ratings";
- N_PICTURES = 12 "pictures";
- N_IDENTIFIERS = 13 "identifiers";
- N_VISIBILITY = 14 "visibility";
- N_STORAGE_SIZE = 15 "storage_size";
+ N_KIND: Tag = 1 "kind";
+ N_TITLE: &str = 2 "title";
+ N_PARENT: u64 = 3 "parent";
+ N_TAGLINE: &str = 4 "tagline";
+ N_DESCRIPTION: &str = 5 "description";
+ N_RELEASEDATE: u64 = 6 "releasedate";
+ N_INDEX: u64 = 7 "index";
+ N_SEASON_INDEX: u64 = 8 "season_index";
+ N_MEDIA: Object = 9 "media";
+ N_TAG: &str = 10 "tag";
+ N_RATINGS: Object = 11 "ratings";
+ N_PICTURES: Object = 12 "pictures";
+ N_IDENTIFIERS: Object = 13 "identifiers";
+ N_VISIBILITY: Tag = 14 "visibility";
+ N_STORAGE_SIZE: u64 = 15 "storage_size";
- LANG_NATIVE = 0xa001 "native";
- LANG_ENG = 0xa002 "eng";
- LANG_DEU = 0xa003 "deu";
- LANG_JPN = 0xa003 "jpn";
+ LANG_NATIVE: &str = 0xa001 "native";
+ LANG_ENG: &str = 0xa002 "eng";
+ LANG_DEU: &str = 0xa003 "deu";
+ LANG_JPN: &str = 0xa003 "jpn";
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]