plux_rs/variable/
var.rs

1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5use crate::utils::ParseVariableError;
6
7#[derive(Default, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
8pub enum Variable {
9    #[default]
10    Null,
11    I8(i8),
12    I16(i16),
13    I32(i32),
14    I64(i64),
15    U8(u8),
16    U16(u16),
17    U32(u32),
18    U64(u64),
19    F32(f32),
20    F64(f64),
21    Bool(bool),
22    Char(char),
23    String(String),
24    List(Vec<Variable>),
25}
26
27pub trait FromVariable {
28    type Output;
29    type RefOutput<'a>
30    where
31        Self: 'a;
32    type MutOutput<'a>
33    where
34        Self: 'a;
35
36    fn from_var(var: Variable) -> Result<Self::Output, ParseVariableError>;
37    fn from_var_ref(var: &Variable) -> Result<Self::RefOutput<'_>, ParseVariableError>;
38    fn from_var_mut(var: &mut Variable) -> Result<Self::MutOutput<'_>, ParseVariableError>;
39}
40
41macro_rules! impl_from {
42    ($ty:ty, $from:ident) => {
43        impl From<$ty> for Variable {
44            fn from(x: $ty) -> Self {
45                Self::$from(x)
46            }
47        }
48    };
49}
50
51macro_rules! impl_from_variable {
52    ($ty:ty, $from:ident) => {
53        impl FromVariable for $ty {
54            type Output = Self;
55            type RefOutput<'a> = &'a Self;
56            type MutOutput<'a> = &'a mut Self;
57
58            fn from_var(var: Variable) -> Result<Self::Output, ParseVariableError> {
59                match var {
60                    Variable::$from(x) => Ok(x),
61                    _ => Err(ParseVariableError::new(stringify!($from))),
62                }
63            }
64
65            fn from_var_ref(var: &Variable) -> Result<Self::RefOutput<'_>, ParseVariableError> {
66                match var {
67                    Variable::$from(x) => Ok(x),
68                    _ => Err(ParseVariableError::new(stringify!($from))),
69                }
70            }
71
72            fn from_var_mut(var: &mut Variable) -> Result<Self::MutOutput<'_>, ParseVariableError> {
73                match var {
74                    Variable::$from(x) => Ok(x),
75                    _ => Err(ParseVariableError::new(stringify!($from))),
76                }
77            }
78        }
79    };
80}
81
82impl From<&str> for Variable {
83    fn from(x: &str) -> Self {
84        Self::String(x.to_string())
85    }
86}
87
88impl<T> From<&[T]> for Variable
89where
90    T: Into<Variable> + Clone,
91{
92    fn from(x: &[T]) -> Self {
93        Self::List(x.iter().cloned().map(|item| item.into()).collect())
94    }
95}
96
97impl<T> From<Vec<T>> for Variable
98where
99    T: Into<Variable>,
100{
101    fn from(x: Vec<T>) -> Self {
102        Self::List(x.into_iter().map(|item| item.into()).collect())
103    }
104}
105
106impl_from!(i8, I8);
107impl_from!(i16, I16);
108impl_from!(i32, I32);
109impl_from!(i64, I64);
110impl_from!(u8, U8);
111impl_from!(u16, U16);
112impl_from!(u32, U32);
113impl_from!(u64, U64);
114impl_from!(f32, F32);
115impl_from!(f64, F64);
116impl_from!(bool, Bool);
117impl_from!(char, Char);
118impl_from!(String, String);
119
120impl Display for Variable {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        match self {
123            Variable::Null => write!(f, "Null"),
124            Variable::I8(v) => write!(f, "{v}"),
125            Variable::I16(v) => write!(f, "{v}"),
126            Variable::I32(v) => write!(f, "{v}"),
127            Variable::I64(v) => write!(f, "{v}"),
128            Variable::U8(v) => write!(f, "{v}"),
129            Variable::U16(v) => write!(f, "{v}"),
130            Variable::U32(v) => write!(f, "{v}"),
131            Variable::U64(v) => write!(f, "{v}"),
132            Variable::F32(v) => write!(f, "{v}"),
133            Variable::F64(v) => write!(f, "{v}"),
134            Variable::Bool(v) => write!(f, "{v}"),
135            Variable::Char(v) => write!(f, "{v}"),
136            Variable::String(v) => write!(f, "{v}"),
137            Variable::List(v) => write!(f, "{v:?}"),
138        }
139    }
140}
141
142impl Variable {
143    pub fn is_null(&self) -> bool {
144        match self {
145            Variable::Null => true,
146            _ => false,
147        }
148    }
149}
150
151impl Variable {
152    pub fn parse<F>(self) -> F::Output
153    where
154        F: FromVariable,
155    {
156        F::from_var(self).unwrap()
157    }
158
159    pub fn parse_ref<F>(&self) -> F::RefOutput<'_>
160    where
161        F: FromVariable,
162    {
163        F::from_var_ref(self).unwrap()
164    }
165
166    pub fn parse_mut<F>(&mut self) -> F::MutOutput<'_>
167    where
168        F: FromVariable,
169    {
170        F::from_var_mut(self).unwrap()
171    }
172
173    pub fn try_parse<F>(self) -> Result<F::Output, ParseVariableError>
174    where
175        F: FromVariable,
176    {
177        F::from_var(self)
178    }
179
180    pub fn try_parse_ref<F>(&self) -> Result<F::RefOutput<'_>, ParseVariableError>
181    where
182        F: FromVariable,
183    {
184        F::from_var_ref(self)
185    }
186
187    pub fn try_parse_mut<F>(&mut self) -> Result<F::MutOutput<'_>, ParseVariableError>
188    where
189        F: FromVariable,
190    {
191        F::from_var_mut(self)
192    }
193}
194
195impl FromVariable for Vec<Variable> {
196    type Output = Self;
197    type RefOutput<'a> = &'a Self;
198    type MutOutput<'a> = &'a mut Self;
199
200    fn from_var(var: Variable) -> Result<Self::Output, ParseVariableError> {
201        match var {
202            Variable::List(x) => Ok(x),
203            _ => Err(ParseVariableError::new("Vec<Variable>")),
204        }
205    }
206
207    fn from_var_ref(var: &Variable) -> Result<Self::RefOutput<'_>, ParseVariableError> {
208        match var {
209            Variable::List(x) => Ok(x),
210            _ => Err(ParseVariableError::new("Vec<Variable>")),
211        }
212    }
213
214    fn from_var_mut(var: &mut Variable) -> Result<Self::MutOutput<'_>, ParseVariableError> {
215        match var {
216            Variable::List(x) => Ok(x),
217            _ => Err(ParseVariableError::new("Vec<Variable>")),
218        }
219    }
220}
221
222impl<T> FromVariable for Vec<T>
223where
224    T: FromVariable,
225{
226    type Output = Vec<T::Output>;
227    type RefOutput<'a> = Vec<T::RefOutput<'a>> where T: 'a;
228    type MutOutput<'a> = Vec<T::MutOutput<'a>> where T: 'a;
229
230    fn from_var(var: Variable) -> Result<Self::Output, ParseVariableError> {
231        match var {
232            Variable::List(x) => {
233                let mut arr = vec![];
234                for var in x.into_iter() {
235                    arr.push(var.try_parse::<T>()?);
236                }
237                Ok(arr)
238            }
239            _ => Err(ParseVariableError::new("Vec<T>")),
240        }
241    }
242
243    fn from_var_ref(var: &Variable) -> Result<Self::RefOutput<'_>, ParseVariableError> {
244        match var {
245            Variable::List(x) => {
246                let mut arr = vec![];
247                for var in x.iter() {
248                    arr.push(var.try_parse_ref::<T>()?);
249                }
250                Ok(arr)
251            }
252            _ => Err(ParseVariableError::new("Vec<T>")),
253        }
254    }
255
256    fn from_var_mut(var: &mut Variable) -> Result<Self::MutOutput<'_>, ParseVariableError> {
257        match var {
258            Variable::List(x) => {
259                let mut arr = vec![];
260                for var in x.iter_mut() {
261                    arr.push(var.try_parse_mut::<T>()?);
262                }
263                Ok(arr)
264            }
265            _ => Err(ParseVariableError::new("Vec<T>")),
266        }
267    }
268}
269
270impl_from_variable!(i8, I8);
271impl_from_variable!(i16, I16);
272impl_from_variable!(i32, I32);
273impl_from_variable!(i64, I64);
274impl_from_variable!(u8, U8);
275impl_from_variable!(u16, U16);
276impl_from_variable!(u32, U32);
277impl_from_variable!(u64, U64);
278impl_from_variable!(f32, F32);
279impl_from_variable!(f64, F64);
280impl_from_variable!(bool, Bool);
281impl_from_variable!(char, Char);
282impl_from_variable!(String, String);
283
284#[test]
285fn into() {
286    let a = 10_i16;
287
288    let b: Variable = a.into();
289    assert_eq!(b, Variable::I16(10));
290}
291
292#[test]
293fn parse() {
294    let mut a: Variable = 10_i16.into();
295
296    assert_eq!(a.clone().parse::<i16>(), 10);
297    assert_eq!(a.parse_ref::<i16>(), &10);
298    assert_eq!(a.parse_mut::<i16>(), &mut 10);
299
300    match a.clone().try_parse::<i16>() {
301        Ok(b) => assert_eq!(b, 10),
302        Err(e) => panic!("{}", e),
303    };
304
305    match a.try_parse_ref::<i16>() {
306        Ok(b) => assert_eq!(b, &10),
307        Err(e) => panic!("{}", e),
308    };
309
310    match a.try_parse_mut::<i16>() {
311        Ok(b) => assert_eq!(b, &mut 10),
312        Err(e) => panic!("{}", e),
313    };
314}
315
316#[test]
317fn parse_vec() {
318    let mut a: Variable = vec![10_i16].into();
319
320    let b = a.parse_mut::<Vec<i16>>();
321
322    assert_eq!(b, vec![&mut 10]);
323}