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}