Skip to main content

aphyn_reflection/
refl_map.rs

1use std::{any::Any, collections::HashMap};
2
3use crate::tuple_from_vec_of_any::TupleFromVecOfAny;
4
5// todo: ffi?
6
7pub enum ReflMapType {
8    Struct(ReflMapStruct),
9}
10
11pub struct ReflMapStruct {
12    factory_raw: *const (),
13    deconstructor_raw: *const (),
14    factory_wrapper: fn(*const (), Vec<Box<dyn Any>>) -> Option<Box<dyn Any>>,
15    deconstructor_wrapper: fn(*const (), Box<dyn Any>) -> Option<Vec<Box<dyn Any>>>,
16    pub fields: HashMap<&'static str, ReflMapStructField>,
17}
18
19impl ReflMapStruct {
20    pub fn new<T: 'static, P: TupleFromVecOfAny>(
21        factory: fn(P) -> T,
22        deconstructor: fn(T) -> P,
23        fields: HashMap<&'static str, ReflMapStructField>,
24    ) -> Self {
25        Self {
26            factory_raw: factory as *const (),
27            deconstructor_raw: deconstructor as *const (),
28            factory_wrapper: move |f, p| {
29                let factory_raw = unsafe { std::mem::transmute::<_, fn(P) -> T>(f) };
30
31                Some(Box::new(factory_raw(P::tuple_from_vec_of_any(p)?)) as Box<dyn Any>)
32            },
33            deconstructor_wrapper: move |f, v| {
34                let deconstructor_raw = unsafe { std::mem::transmute::<_, fn(T) -> P>(f) };
35
36                Some(P::tuple_into_vec_of_any(deconstructor_raw(*v.downcast().ok()?)))
37            },
38            fields,
39        }
40    }
41    pub fn create(&self, parameters: Vec<Box<dyn Any>>) -> Option<Box<dyn Any>> {
42        (self.factory_wrapper)(self.factory_raw, parameters)
43    }
44    pub fn deconstruct(&self, v: Box<dyn Any>) -> Option<Vec<Box<dyn Any>>> {
45        (self.deconstructor_wrapper)(self.deconstructor_raw, v)
46    }
47}
48
49pub struct ReflMapStructField {
50    ref_getter_raw: *const (),
51    mut_getter_raw: *const (),
52    ref_getter_wrapper: fn(*const (), &dyn Any) -> Option<&dyn Any>,
53    mut_getter_wrapper: fn(*const (), &mut dyn Any) -> Option<&mut dyn Any>,
54}
55
56impl ReflMapStructField {
57    pub fn new<T: 'static, F: 'static>(ref_getter: fn(&T) -> &F, mut_getter: fn(&mut T) -> &mut F) -> Self {
58        Self {
59            ref_getter_raw: ref_getter as *const (),
60            mut_getter_raw: mut_getter as *const (),
61            ref_getter_wrapper: |raw, v| {
62                let ref_getter_raw = unsafe { std::mem::transmute::<*const (), fn(&T) -> &F>(raw) };
63
64                Some(ref_getter_raw(v.downcast_ref()?))
65            },
66            mut_getter_wrapper: |raw, v| {
67                let mut_getter_raw = unsafe { std::mem::transmute::<*const (), fn(&mut T) -> &mut F>(raw) };
68
69                Some(mut_getter_raw(v.downcast_mut()?))
70            },
71        }
72    }
73    pub fn get_ref<'a>(&self, v: &'a dyn Any) -> Option<&'a dyn Any> {
74        (self.ref_getter_wrapper)(self.ref_getter_raw, v)
75    }
76    pub fn get_mut<'a>(&self, v: &'a mut dyn Any) -> Option<&'a mut dyn Any> {
77        (self.mut_getter_wrapper)(self.mut_getter_raw, v)
78    }
79}
80
81// todo: enum
82// todo: collections
83// todo: generics?