1use lotus_script_sys::{FfiObject, FromFfi};
2use lotus_shared::content::ContentId;
3
4pub trait VariableType {
5 type Output;
6
7 fn get(name: &str) -> Self::Output;
8 fn set(&self, name: &str);
9}
10
11pub enum Persistence {
12 Session,
13 Permanent,
14}
15
16macro_rules! impl_variable_type {
17 ($type:ty, $get:ident, $set:ident) => {
18 impl VariableType for $type {
19 type Output = $type;
20
21 fn get(name: &str) -> Self::Output {
22 let name = FfiObject::new(&name);
23 unsafe { lotus_script_sys::var::$get(name.packed()) as _ }
24 }
25
26 fn set(&self, name: &str) {
27 let name = FfiObject::new(&name);
28 unsafe { lotus_script_sys::var::$set(name.packed(), *self as _) }
29 }
30 }
31 };
32}
33
34impl_variable_type!(i8, get_i64, set_i64);
35impl_variable_type!(i16, get_i64, set_i64);
36impl_variable_type!(i32, get_i64, set_i64);
37impl_variable_type!(i64, get_i64, set_i64);
38
39impl_variable_type!(u8, get_i64, set_i64);
40impl_variable_type!(u16, get_i64, set_i64);
41impl_variable_type!(u32, get_i64, set_i64);
42impl_variable_type!(u64, get_i64, set_i64);
43
44impl_variable_type!(f32, get_f64, set_f64);
45impl_variable_type!(f64, get_f64, set_f64);
46
47impl VariableType for bool {
48 type Output = bool;
49
50 fn get(name: &str) -> Self::Output {
51 let name = FfiObject::new(&name);
52 unsafe { lotus_script_sys::var::get_bool(name.packed()) != 0 }
53 }
54
55 fn set(&self, name: &str) {
56 let name = FfiObject::new(&name);
57 unsafe {
58 lotus_script_sys::var::set_bool(
59 name.packed(),
60 match self {
61 true => 1,
62 false => 0,
63 },
64 )
65 }
66 }
67}
68
69impl VariableType for String {
70 type Output = String;
71
72 fn get(name: &str) -> Self::Output {
73 let name = FfiObject::new(&name);
74 let ptr = unsafe { lotus_script_sys::var::get_string(name.packed()) };
75 String::from_ffi(ptr)
76 }
77
78 fn set(&self, name: &str) {
79 let name = FfiObject::new(&name);
80 let value = FfiObject::new(self);
81 unsafe { lotus_script_sys::var::set_string(name.packed(), value.packed()) }
82 }
83}
84
85impl VariableType for &str {
86 type Output = String;
87
88 fn get(name: &str) -> Self::Output {
89 let name = FfiObject::new(&name);
90 let ptr = unsafe { lotus_script_sys::var::get_string(name.packed()) };
91 String::from_ffi(ptr)
92 }
93
94 fn set(&self, name: &str) {
95 let name = FfiObject::new(&name);
96 let value = FfiObject::new(&self.to_string());
97 unsafe { lotus_script_sys::var::set_string(name.packed(), value.packed()) }
98 }
99}
100
101impl VariableType for ContentId {
102 type Output = ContentId;
103
104 fn get(name: &str) -> Self {
105 let name = FfiObject::new(&name);
106 let ptr = unsafe { lotus_script_sys::var::get_content_id(name.packed()) };
107 FfiObject::from_packed(ptr).deserialize()
108 }
109
110 fn set(&self, name: &str) {
111 let name = FfiObject::new(&name);
112 let value = FfiObject::new(self);
113 unsafe { lotus_script_sys::var::set_content_id(name.packed(), value.packed()) }
114 }
115}
116
117pub struct Variable<T> {
118 name: String,
119 _phantom: std::marker::PhantomData<T>,
120}
121
122impl<T> Variable<T> {
123 pub fn new(name: &str) -> Self {
124 Self {
125 name: name.to_string(),
126 _phantom: std::marker::PhantomData,
127 }
128 }
129}
130
131impl<T: VariableType> Variable<T> {
132 pub fn get(&self) -> T::Output {
133 T::get(&self.name)
134 }
135
136 pub fn set(&self, value: &T) {
137 value.set(&self.name);
138 }
139}