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 } }
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}