/* 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 */ use crate::Tag; use std::{any::TypeId, collections::BTreeMap}; pub mod types { use crate::Object; use std::any::TypeId; pub const OBJECT: TypeId = TypeId::of::(); pub const STR: TypeId = TypeId::of::<&str>(); pub const U32: TypeId = TypeId::of::(); pub const U64: TypeId = TypeId::of::(); } #[derive(Default)] pub struct Registry { tags: BTreeMap, } impl Registry { pub fn add(&mut self, tag: Tag, info: TagInfo) { if let Some(other) = self.tags.get(&tag) { panic!( "Conflicting names for tag {}: {:?} vs {:?}", tag.0, info.name, other.name ) } self.tags.insert(tag, info); } pub fn info(&self, tag: Tag) -> Option<&TagInfo> { self.tags.get(&tag) } pub fn name(&self, tag: Tag) -> &str { match self.tags.get(&tag) { Some(inf) => inf.name, None => "unknown", } } } pub struct TagInfo { pub name: &'static str, pub r#type: Option, } #[macro_export] macro_rules! fields { ($($id:ident: $type:ty = $tag:literal $name:literal;)*) => { $(pub const $id: $crate::TypedTag<$type> = $crate::TypedTag($crate::Tag($tag), std::marker::PhantomData);)* pub(crate) fn register_fields(reg: &mut $crate::Registry) { $(reg.add($crate::Tag($tag), $crate::TagInfo { name: $name, r#type: Some(std::any::TypeId::of::<$type>()) });)* } }; } #[macro_export] macro_rules! enums { ($($id:ident = $tag:literal $name:literal;)*) => { $(pub const $id: $crate::Tag = $crate::Tag($tag);)* pub(crate) fn register_enums(reg: &mut $crate::Registry) { $(reg.add($crate::Tag($tag), $crate::TagInfo { name: $name, r#type: None });)* } }; }