trs_data_value/
from.rs

1use std::collections::HashMap;
2
3use super::DataValue;
4
5impl From<()> for DataValue {
6    fn from(_value: ()) -> Self {
7        DataValue::Null
8    }
9}
10
11impl From<u32> for DataValue {
12    fn from(value: u32) -> Self {
13        DataValue::U32(value)
14    }
15}
16impl From<usize> for DataValue {
17    fn from(value: usize) -> Self {
18        DataValue::U32(value as u32)
19    }
20}
21impl From<i32> for DataValue {
22    fn from(value: i32) -> Self {
23        DataValue::I32(value)
24    }
25}
26impl From<u8> for DataValue {
27    fn from(value: u8) -> Self {
28        DataValue::U8(value)
29    }
30}
31impl From<u64> for DataValue {
32    fn from(value: u64) -> Self {
33        DataValue::U64(value)
34    }
35}
36impl From<i64> for DataValue {
37    fn from(value: i64) -> Self {
38        DataValue::I64(value)
39    }
40}
41impl From<f32> for DataValue {
42    fn from(value: f32) -> Self {
43        DataValue::F32(value)
44    }
45}
46impl From<u128> for DataValue {
47    fn from(value: u128) -> Self {
48        DataValue::U128(value)
49    }
50}
51impl From<i128> for DataValue {
52    fn from(value: i128) -> Self {
53        DataValue::I128(value)
54    }
55}
56impl From<f64> for DataValue {
57    fn from(value: f64) -> Self {
58        DataValue::F64(value)
59    }
60}
61impl From<String> for DataValue {
62    fn from(value: String) -> Self {
63        DataValue::String(value.into())
64    }
65}
66
67impl From<smartstring::alias::String> for DataValue {
68    fn from(value: smartstring::alias::String) -> Self {
69        DataValue::String(value)
70    }
71}
72
73impl From<&str> for DataValue {
74    fn from(value: &str) -> Self {
75        DataValue::String(value.into())
76    }
77}
78
79impl From<Vec<u8>> for DataValue {
80    fn from(value: Vec<u8>) -> Self {
81        DataValue::Bytes(value)
82    }
83}
84impl From<bool> for DataValue {
85    fn from(value: bool) -> Self {
86        DataValue::Bool(value)
87    }
88}
89impl From<Option<String>> for DataValue {
90    fn from(value: Option<String>) -> Self {
91        match value {
92            Some(value) => DataValue::String(value.into()),
93            None => DataValue::Null,
94        }
95    }
96}
97
98impl From<Option<smartstring::alias::String>> for DataValue {
99    fn from(value: Option<smartstring::alias::String>) -> Self {
100        match value {
101            Some(value) => DataValue::String(value),
102            None => DataValue::Null,
103        }
104    }
105}
106impl From<Option<&str>> for DataValue {
107    fn from(value: Option<&str>) -> Self {
108        DataValue::from(value.map(|x| x.to_string()))
109    }
110}
111impl From<Option<&String>> for DataValue {
112    fn from(value: Option<&String>) -> Self {
113        DataValue::from(value.cloned())
114    }
115}
116impl From<Option<&smartstring::alias::String>> for DataValue {
117    fn from(value: Option<&smartstring::alias::String>) -> Self {
118        DataValue::from(value.cloned())
119    }
120}
121impl From<Vec<DataValue>> for DataValue {
122    fn from(value: Vec<DataValue>) -> Self {
123        DataValue::Vec(value)
124    }
125}
126
127impl From<Vec<String>> for DataValue {
128    fn from(value: Vec<String>) -> Self {
129        DataValue::Vec(value.into_iter().map(|x| x.into()).collect())
130    }
131}
132
133impl From<&[u8]> for DataValue {
134    fn from(value: &[u8]) -> Self {
135        DataValue::Bytes(value.to_vec())
136    }
137}
138
139impl From<Vec<smartstring::alias::String>> for DataValue {
140    fn from(value: Vec<smartstring::alias::String>) -> Self {
141        DataValue::Vec(value.into_iter().map(|x| x.into()).collect())
142    }
143}
144impl From<Vec<usize>> for DataValue {
145    fn from(value: Vec<usize>) -> Self {
146        DataValue::Vec(value.into_iter().map(|x| (x as u32).into()).collect())
147    }
148}
149impl From<HashMap<String, DataValue>> for DataValue {
150    fn from(value: HashMap<String, DataValue>) -> Self {
151        DataValue::Map(value.into_iter().map(|(k, v)| (k.into(), v)).collect())
152    }
153}
154
155impl From<HashMap<smartstring::alias::String, DataValue>> for DataValue {
156    fn from(value: HashMap<smartstring::alias::String, DataValue>) -> Self {
157        DataValue::Map(value)
158    }
159}
160
161impl From<&prost_reflect::Value> for DataValue {
162    fn from(proto_value: &prost_reflect::Value) -> Self {
163        match proto_value {
164            prost_reflect::Value::Bool(b) => DataValue::Bool(*b),
165            prost_reflect::Value::I32(b) => DataValue::I32(*b),
166            prost_reflect::Value::I64(b) => DataValue::I64(*b),
167            prost_reflect::Value::U32(b) => DataValue::U32(*b),
168            prost_reflect::Value::U64(b) => DataValue::U64(*b),
169            prost_reflect::Value::F32(b) => DataValue::F32(*b),
170            prost_reflect::Value::F64(b) => DataValue::F64(*b),
171            prost_reflect::Value::String(b) => DataValue::String(b.into()),
172            prost_reflect::Value::Bytes(b) => DataValue::Bytes(b.to_vec()),
173            prost_reflect::Value::EnumNumber(b) => DataValue::EnumNumber(*b),
174            prost_reflect::Value::List(b) => DataValue::Vec(b.iter().map(|x| x.into()).collect()),
175            prost_reflect::Value::Map(b) => DataValue::Map(
176                b.iter()
177                    .map(|(k, v)| {
178                        let key = match k {
179                            prost_reflect::MapKey::String(k) => k.clone(),
180                            prost_reflect::MapKey::U32(k) => k.to_string(),
181                            prost_reflect::MapKey::U64(k) => k.to_string(),
182                            prost_reflect::MapKey::I32(k) => k.to_string(),
183                            prost_reflect::MapKey::I64(k) => k.to_string(),
184                            prost_reflect::MapKey::Bool(k) => k.to_string(),
185                        };
186                        (key.into(), DataValue::from(v))
187                    })
188                    .collect::<HashMap<_, _>>(),
189            ),
190            e => {
191                tracing::trace!("e: {:?}", e);
192                DataValue::Null
193            } /*prost_reflect::Value::Message(b) => {
194                  DataValue::Map(b.iter_fields().map(|(k, v)| (k.into(), v.into())).collect())
195              }*/
196        }
197    }
198}
199impl From<prost_reflect::Value> for DataValue {
200    fn from(proto_value: prost_reflect::Value) -> Self {
201        DataValue::from(&proto_value)
202    }
203}
204impl From<&serde_json::Value> for DataValue {
205    fn from(proto_value: &serde_json::Value) -> Self {
206        match proto_value {
207            serde_json::Value::Bool(b) => DataValue::Bool(*b),
208            serde_json::Value::Number(b) => {
209                if b.is_i64() {
210                    DataValue::I64(b.as_i64().expect("BUG: should be i64"))
211                } else if b.is_u64() {
212                    DataValue::U64(b.as_u64().expect("BUG: should be u64"))
213                } else {
214                    DataValue::F64(b.as_f64().expect("BUG: should be f64"))
215                }
216            }
217            serde_json::Value::String(b) => DataValue::String(b.into()),
218            serde_json::Value::Null => DataValue::Null,
219            serde_json::Value::Array(v) => DataValue::Vec(v.iter().map(DataValue::from).collect()),
220            serde_json::Value::Object(v) => DataValue::Map(
221                v.iter()
222                    .map(|(k, v)| (k.clone().into(), DataValue::from(v)))
223                    .collect(),
224            ),
225        }
226    }
227}
228impl From<serde_json::Value> for DataValue {
229    fn from(proto_value: serde_json::Value) -> Self {
230        DataValue::from(&proto_value)
231    }
232}
233
234use base64::{
235    alphabet,
236    engine::{self, general_purpose},
237    Engine as _,
238};
239const CUSTOM_ENGINE: engine::GeneralPurpose =
240    engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
241use serde_json::json;
242
243impl DataValue {
244    #[inline]
245    pub fn to_json(self) -> serde_json::Value {
246        match self {
247            DataValue::Bool(b) => serde_json::Value::Bool(b),
248            DataValue::U32(b) => serde_json::Value::Number(b.into()),
249            DataValue::I32(b) => serde_json::Value::Number(b.into()),
250            DataValue::U8(b) => serde_json::Value::Number(b.into()),
251            DataValue::U64(b) => serde_json::Value::Number(b.into()),
252            DataValue::I64(b) => serde_json::Value::Number(b.into()),
253            DataValue::F32(b) => json!(b),
254            DataValue::F64(b) => json!(b),
255            DataValue::U128(b) => json!(b),
256            DataValue::I128(b) => json!(b),
257            DataValue::String(b) => serde_json::Value::String(b.into()),
258            DataValue::Bytes(b) => serde_json::Value::String(CUSTOM_ENGINE.encode(b)),
259            DataValue::Null => serde_json::Value::Null,
260            DataValue::Vec(b) => {
261                serde_json::Value::Array(b.into_iter().map(|x| x.to_json()).collect())
262            }
263            DataValue::Map(b) => serde_json::Value::Object(
264                b.into_iter()
265                    .map(|(k, v)| (k.to_string(), v.to_json()))
266                    .collect(),
267            ),
268            DataValue::EnumNumber(b) => serde_json::Value::Number(b.into()),
269        }
270    }
271}
272
273#[cfg(test)]
274mod test {
275    use super::*;
276    use rstest::*;
277
278    #[rstest]
279    fn data_value_from() {
280        assert_eq!(
281            DataValue::String("key".into()),
282            DataValue::from(Some("key"))
283        );
284        assert_eq!(
285            DataValue::String("key".into()),
286            DataValue::from(Some("key".to_string()))
287        );
288        assert_eq!(
289            DataValue::String("key".into()),
290            DataValue::from(Some(smartstring::alias::String::from("key")))
291        );
292        assert_eq!(
293            DataValue::String("key".into()),
294            DataValue::from(Some(&smartstring::alias::String::from("key")))
295        );
296
297        assert_eq!(
298            DataValue::Vec(vec![DataValue::String("key".into())]),
299            DataValue::Vec(vec![DataValue::from(Some("key"))])
300        );
301        assert_eq!(
302            DataValue::Vec(vec![DataValue::String("key".into())]),
303            DataValue::Vec(vec![DataValue::from(smartstring::alias::String::from(
304                "key"
305            ))])
306        );
307
308        let map: HashMap<String, DataValue> =
309            crate::stdhashmap!(String::from("key") => DataValue::String("key".into()));
310        assert_eq!(
311            DataValue::from(map),
312            DataValue::Map(crate::stdhashmap!("key" => DataValue::from("key")))
313        );
314        let map: HashMap<smartstring::alias::String, DataValue> = crate::stdhashmap!(smartstring::alias::String::from("key") => DataValue::String("key".into()));
315        assert_eq!(
316            DataValue::from(map),
317            DataValue::Map(crate::stdhashmap!("key" => DataValue::from("key")))
318        );
319    }
320
321    #[rstest]
322    #[case(DataValue::U32(12), serde_json::json!(12))]
323    #[case(DataValue::I32(12), serde_json::json!(12))]
324    #[case(DataValue::I64(12), serde_json::json!(12))]
325    #[case(DataValue::U64(12), serde_json::json!(12))]
326    #[case(DataValue::F32(12f32), serde_json::json!(12f32))]
327    #[case(DataValue::F64(12f64), serde_json::json!(12f64))]
328    #[case(DataValue::U8(12), serde_json::json!(12))]
329    #[case(DataValue::U128(12), serde_json::json!(12))]
330    #[case(DataValue::I128(12), serde_json::json!(12))]
331    #[case(DataValue::Bool(true), serde_json::json!(true))]
332    #[case(DataValue::Null, serde_json::json!(null))]
333    #[case(DataValue::Vec(vec![1.into(),2.into(),3.into(),4.into()]), serde_json::json!(vec![1,2,3,4]))]
334    #[case(DataValue::String("test".into()), serde_json::json!("test"))]
335    #[case(DataValue::Map(crate::stdhashmap!("key" => "test")), serde_json::json!({"key": "test"}))]
336    #[case(DataValue::Bytes(vec![1,2,3,4]), serde_json::json!("AQIDBA"))]
337    fn from_json(#[case] input: DataValue, #[case] expected: serde_json::Value) {
338        assert_eq!(input.to_json(), expected);
339    }
340
341    #[rstest]
342    #[case(DataValue::I64(i64::MAX), serde_json::json!(i64::MAX))]
343    #[case(DataValue::I64(i32::MAX as i64), serde_json::json!(i32::MAX))]
344    #[case(DataValue::F64(f32::MAX as f64), serde_json::json!(f32::MAX))]
345    #[case(DataValue::F64(f64::MAX), serde_json::json!(f64::MAX))]
346    #[case(DataValue::Bool(true), serde_json::json!(true))]
347    #[case(DataValue::Null, serde_json::json!(null))]
348    #[case(DataValue::Vec(vec![1i64.into(),2i64.into(),3i64.into(),4i64.into()]), serde_json::json!(vec![1,2,3,4]))]
349    #[case(DataValue::String("test".into()), serde_json::json!("test"))]
350    #[case(DataValue::Map(crate::stdhashmap!("key" => "test")), serde_json::json!({"key": "test"}))]
351    fn to_json(#[case] expected: DataValue, #[case] input: serde_json::Value) {
352        assert_eq!(DataValue::from(&input), expected);
353    }
354
355    #[rstest]
356    #[case(DataValue::I64(i64::MAX), prost_reflect::Value::I64(i64::MAX))]
357    #[case(DataValue::I32(i32::MAX), prost_reflect::Value::I32(i32::MAX))]
358    #[case(DataValue::F32(f32::MAX), prost_reflect::Value::F32(f32::MAX))]
359    #[case(DataValue::F64(f64::MAX), prost_reflect::Value::F64(f64::MAX))]
360    #[case(DataValue::Bool(true), prost_reflect::Value::Bool(true))]
361    #[case(DataValue::Vec(vec![1i64.into(),2i64.into(),3i64.into(),4i64.into()]), prost_reflect::Value::List(vec![prost_reflect::Value::I64(1),prost_reflect::Value::I64(2),prost_reflect::Value::I64(3),prost_reflect::Value::I64(4)]))]
362    #[case(DataValue::String("test".into()), prost_reflect::Value::String("test".to_string()))]
363    #[case(DataValue::Map(crate::stdhashmap!("key" => "test")), prost_reflect::Value::Map(crate::stdhashmap!(prost_reflect::MapKey::String("key".to_string()) => prost_reflect::Value::String("test".to_string()))))]
364    fn from_prost(#[case] expected: DataValue, #[case] input: prost_reflect::Value) {
365        assert_eq!(DataValue::from(&input), expected);
366    }
367}