lotus_script/
public_vars.rs

1use crate::var::VariableType;
2
3pub struct PublicVar<T> {
4    name: &'static str,
5    _phantom: std::marker::PhantomData<T>,
6}
7
8impl<T> PublicVar<T>
9where
10    T: PublicVarType + VariableType,
11{
12    pub const fn new(name: &'static str) -> Self {
13        Self {
14            name,
15            _phantom: std::marker::PhantomData,
16        }
17    }
18
19    pub fn type_name(&self) -> &'static str {
20        T::type_name()
21    }
22
23    pub fn get(&self) -> T::Output {
24        T::get(self.name)
25    }
26
27    pub fn set(&self, value: T) {
28        value.set(self.name)
29    }
30}
31
32pub trait PublicVarType {
33    fn type_name() -> &'static str;
34}
35
36macro_rules! impl_public_var_type {
37    ($type:ty, $name:ident) => {
38        impl PublicVarType for $type {
39            fn type_name() -> &'static str {
40                stringify!($name)
41            }
42        }
43    };
44}
45
46impl_public_var_type!(i32, i32);
47impl_public_var_type!(i64, i64);
48
49impl_public_var_type!(u32, u32);
50impl_public_var_type!(u64, u64);
51
52impl_public_var_type!(f32, f32);
53impl_public_var_type!(f64, f64);
54
55impl_public_var_type!(bool, bool);
56impl_public_var_type!(String, string);
57
58#[macro_export]
59macro_rules! public_vars {
60    ($($name:ident: $type:ty),* $(,)?) => {
61        pub mod pub_var {
62            $(
63                #[allow(non_upper_case_globals)]
64                pub const $name: $crate::public_vars::PublicVar<$type> = $crate::public_vars::PublicVar::new(stringify!($name));
65            )*
66        }
67        #[no_mangle]
68        pub fn public_vars() -> u64 {
69            use $crate::public_vars::PublicVarType;
70            let vars = vec![
71                $(
72                    (stringify!($name), pub_var::$name.type_name()),
73                )*
74            ];
75
76            $crate::FfiObject::new(&vars).packed_forget()
77        }
78    };
79}