zen_types/variable/
impls.rs

1use crate::variable::Variable;
2use rust_decimal::Decimal;
3use rust_decimal::prelude::FromPrimitive;
4use serde_json::Value;
5use std::collections::HashMap;
6use std::ops::Deref;
7use std::rc::Rc;
8use std::sync::Arc;
9
10pub trait ToVariable {
11    fn to_variable(&self) -> Variable;
12}
13
14impl ToVariable for String {
15    fn to_variable(&self) -> Variable {
16        Variable::String(Rc::from(self.as_str()))
17    }
18}
19
20impl ToVariable for str {
21    fn to_variable(&self) -> Variable {
22        Variable::String(Rc::from(self))
23    }
24}
25
26impl ToVariable for bool {
27    fn to_variable(&self) -> Variable {
28        Variable::Bool(*self)
29    }
30}
31
32impl ToVariable for Decimal {
33    fn to_variable(&self) -> Variable {
34        Variable::Number(*self)
35    }
36}
37
38impl ToVariable for Variable {
39    fn to_variable(&self) -> Variable {
40        self.clone()
41    }
42}
43
44impl ToVariable for Value {
45    fn to_variable(&self) -> Variable {
46        Variable::from(self)
47    }
48}
49
50macro_rules! impl_to_variable_numeric {
51    ($($t:ty),* $(,)?) => {
52        $(
53            impl ToVariable for $t {
54                fn to_variable(&self) -> Variable {
55                    Variable::Number(Decimal::from(*self))
56                }
57            }
58        )*
59    };
60}
61
62impl_to_variable_numeric!(
63    i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
64);
65
66impl ToVariable for f32 {
67    fn to_variable(&self) -> Variable {
68        Variable::Number(Decimal::from_f32(*self).unwrap_or_default())
69    }
70}
71
72impl ToVariable for f64 {
73    fn to_variable(&self) -> Variable {
74        Variable::Number(Decimal::from_f64(*self).unwrap_or_default())
75    }
76}
77
78impl<T> ToVariable for Vec<T>
79where
80    T: ToVariable,
81{
82    fn to_variable(&self) -> Variable {
83        Variable::from_array(self.iter().map(|v| v.to_variable()).collect())
84    }
85}
86
87impl<V, S> ToVariable for HashMap<Rc<str>, V, S>
88where
89    V: ToVariable,
90    S: std::hash::BuildHasher,
91{
92    fn to_variable(&self) -> Variable {
93        Variable::from_object(
94            self.iter()
95                .map(|(k, v)| (k.clone(), v.to_variable()))
96                .collect(),
97        )
98    }
99}
100
101impl<V, S> ToVariable for HashMap<Arc<str>, V, S>
102where
103    V: ToVariable,
104    S: std::hash::BuildHasher,
105{
106    fn to_variable(&self) -> Variable {
107        Variable::from_object(
108            self.iter()
109                .map(|(k, v)| (Rc::<str>::from(k.deref()), v.to_variable()))
110                .collect(),
111        )
112    }
113}
114
115impl<V, S> ToVariable for HashMap<String, V, S>
116where
117    V: ToVariable,
118    S: std::hash::BuildHasher,
119{
120    fn to_variable(&self) -> Variable {
121        Variable::from_object(
122            self.iter()
123                .map(|(k, v)| (Rc::from(k.as_str()), v.to_variable()))
124                .collect(),
125        )
126    }
127}
128
129macro_rules! tuple_impls {
130    ( $( ($($T:ident),+) ),+ ) => {
131        $(
132            impl<$($T),+> ToVariable for ($($T,)+)
133            where
134                $($T: ToVariable,)+
135            {
136                #[allow(non_snake_case)]
137                fn to_variable(&self) -> Variable {
138                    let ($($T,)+) = self;
139                    Variable::from_array(vec![
140                        $($T.to_variable(),)+
141                    ])
142                }
143            }
144        )+
145    };
146}
147
148tuple_impls! {
149    (T1),
150    (T1, T2),
151    (T1, T2, T3),
152    (T1, T2, T3, T4),
153    (T1, T2, T3, T4, T5)
154}
155
156impl<T> ToVariable for &T
157where
158    T: ?Sized + ToVariable,
159{
160    fn to_variable(&self) -> Variable {
161        (**self).to_variable()
162    }
163}
164
165impl<T> ToVariable for &mut T
166where
167    T: ?Sized + ToVariable,
168{
169    fn to_variable(&self) -> Variable {
170        (**self).to_variable()
171    }
172}
173
174impl<T> ToVariable for Option<T>
175where
176    T: ToVariable,
177{
178    fn to_variable(&self) -> Variable {
179        match self {
180            Some(value) => value.to_variable(),
181            None => Variable::Null,
182        }
183    }
184}
185
186impl<T> ToVariable for Box<T>
187where
188    T: ?Sized + ToVariable,
189{
190    fn to_variable(&self) -> Variable {
191        (**self).to_variable()
192    }
193}
194
195impl<T> ToVariable for Rc<T>
196where
197    T: ?Sized + ToVariable,
198{
199    fn to_variable(&self) -> Variable {
200        (**self).to_variable()
201    }
202}
203
204impl<T> ToVariable for Arc<T>
205where
206    T: ?Sized + ToVariable,
207{
208    fn to_variable(&self) -> Variable {
209        (**self).to_variable()
210    }
211}