aphyn_reflection/
registry.rs1use std::{
2 any::{Any, TypeId},
3 collections::HashMap,
4};
5
6use crate::{
7 refl_repr::{ReflRepr, ReflReprFields, ReflReprStruct},
8 refl_repr_reg_entries,
9 refl_ty::{ReflTy, ReflTyId},
10};
11
12#[derive(Default)]
15pub struct ReflTyRegistry {
16 pub types: HashMap<ReflTyId, ReflTy>,
17}
18
19impl ReflTyRegistry {
20 pub fn set(&mut self, id: ReflTyId, ty: ReflTy) {
21 self.types.insert(id, ty);
22 }
23
24 pub fn get(&self, id: &ReflTyId) -> Option<&ReflTy> {
25 self.types.get(id)
26 }
27}
28
29#[derive(Default)]
30pub struct ReflRepresenterRegistry {
31 pub representers: HashMap<TypeId, Box<dyn Any>>,
32}
33
34impl ReflRepresenterRegistry {
35 pub fn set<T: 'static>(&mut self, representer: Box<dyn ReflRepresenter<Item = T>>) {
36 let any = Box::new(representer) as Box<dyn Any>;
37
38 self.representers.insert(TypeId::of::<T>(), any);
39 }
40 pub fn get<T: 'static>(&self) -> Option<&dyn ReflRepresenter<Item = T>> {
41 let any = self.representers.get(&TypeId::of::<T>())?;
42
43 Some(&**(any.downcast_ref::<Box<dyn ReflRepresenter<Item = T>>>()?))
44 }
45
46 pub fn item_name<T: 'static>(&self) -> Option<String> {
47 Some(self.get::<T>()?.item_name(&ReflRepresenterCtx { reg: self }))
48 }
49 pub fn into_repr<T: 'static>(&self, v: &T) -> Option<ReflRepr> {
50 self.get::<T>()?.into_repr(&ReflRepresenterCtx { reg: self }, v)
51 }
52 pub fn from_repr<T: 'static>(&self, v: &ReflRepr) -> Option<T> {
53 self.get::<T>()?.from_repr(&ReflRepresenterCtx { reg: self }, v)
54 }
55}
56
57pub struct ReflRepresenterCtx<'a> {
58 reg: &'a ReflRepresenterRegistry,
59}
60
61impl<'a> ReflRepresenterCtx<'a> {
62 pub fn item_name<T: 'static>(&self) -> Option<String> {
63 Some(self.reg.get::<T>()?.item_name(self))
64 }
65 pub fn into_repr<T: 'static>(&self, v: &T) -> Option<ReflRepr> {
66 self.reg.get::<T>()?.into_repr(self, v)
67 }
68 pub fn from_repr<T: 'static>(&self, v: &ReflRepr) -> Option<T> {
69 self.reg.get::<T>()?.from_repr(self, v)
70 }
71}
72
73pub trait ReflRepresenter {
74 type Item;
75
76 fn item_name(&self, ctx: &ReflRepresenterCtx) -> String;
77 fn into_repr(&self, ctx: &ReflRepresenterCtx, v: &Self::Item) -> Option<ReflRepr>;
78 fn from_repr(&self, ctx: &ReflRepresenterCtx, v: &ReflRepr) -> Option<Self::Item> {
79 None
80 }
81}
82
83#[derive(Debug)]
86pub struct ExampleStruct {
87 pub age: u8,
88 pub name: Option<String>,
89}
90
91pub fn registry_use_case() {
92 let mut reg = ReflRepresenterRegistry::default();
93
94 refl_repr_reg_entries::set_common_representers(&mut reg);
95
96 reg.set(Box::new(ExampleStructReflRepresenter::default()));
97
98 let example_struct = ExampleStruct {
99 age: 55,
100 name: Some(String::from("Barry")),
101 };
102
103 let repr = reg.into_repr(&example_struct).unwrap();
104
105 println!("{:?}", repr);
106 println!("{:?}", example_struct);
107}
108
109#[derive(Default)]
110struct ExampleStructReflRepresenter;
111impl ReflRepresenter for ExampleStructReflRepresenter {
112 type Item = ExampleStruct;
113
114 fn item_name(&self, _ctx: &ReflRepresenterCtx) -> String {
115 String::from("ExampleStruct")
116 }
117
118 fn into_repr(&self, ctx: &ReflRepresenterCtx, v: &Self::Item) -> Option<ReflRepr> {
119 Some(ReflRepr::Struct(ReflReprStruct {
120 name: String::from("ExampleStruct"),
121 fields: ReflReprFields::Named(vec![
122 (String::from("age"), ctx.into_repr(&v.age)?),
123 (String::from("name"), ctx.into_repr(&v.name)?),
124 ]),
125 }))
126 }
127}