zino_core/extension/
json_object.rs

1use super::JsonValueExt;
2use crate::{
3    JsonValue, Map, Record, Uuid,
4    datetime::{self, Date, DateTime, Time},
5    helper,
6    model::Model,
7    validation::Validation,
8};
9use chrono::NaiveDateTime;
10use convert_case::{Case, Casing};
11use rust_decimal::Decimal;
12use std::{
13    borrow::Cow,
14    mem,
15    net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr},
16    num::{ParseFloatError, ParseIntError},
17    str::{FromStr, ParseBoolError},
18    time::Duration,
19};
20use url::Url;
21
22/// Extension trait for [`Map`](crate::Map).
23pub trait JsonObjectExt {
24    /// Extracts the boolean value corresponding to the key.
25    fn get_bool(&self, key: &str) -> Option<bool>;
26
27    /// Extracts the integer value corresponding to the key
28    /// and represents it as `u8` if possible.
29    fn get_u8(&self, key: &str) -> Option<u8>;
30
31    /// Extracts the integer value corresponding to the key
32    /// and represents it as `u16` if possible.
33    fn get_u16(&self, key: &str) -> Option<u16>;
34
35    /// Extracts the integer value corresponding to the key
36    /// and represents it as `u32` if possible.
37    fn get_u32(&self, key: &str) -> Option<u32>;
38
39    /// Extracts the integer value corresponding to the key
40    /// and represents it as `u64` if possible.
41    fn get_u64(&self, key: &str) -> Option<u64>;
42
43    /// Extracts the integer value corresponding to the key
44    /// and represents it as `usize` if possible.
45    fn get_usize(&self, key: &str) -> Option<usize>;
46
47    /// Extracts the integer value corresponding to the key
48    /// and represents it as `i8` if possible.
49    fn get_i8(&self, key: &str) -> Option<i8>;
50
51    /// Extracts the integer value corresponding to the key
52    /// and represents it as `i16` if possible.
53    fn get_i16(&self, key: &str) -> Option<i16>;
54
55    /// Extracts the integer value corresponding to the key
56    /// and represents it as `i32` if possible.
57    fn get_i32(&self, key: &str) -> Option<i32>;
58
59    /// Extracts the integer value corresponding to the key.
60    fn get_i64(&self, key: &str) -> Option<i64>;
61
62    /// Extracts the integer value corresponding to the key
63    /// and represents it as `isize` if possible.
64    fn get_isize(&self, key: &str) -> Option<isize>;
65
66    /// Extracts the float value corresponding to the key
67    /// and represents it as `f32` if possible.
68    fn get_f32(&self, key: &str) -> Option<f32>;
69
70    /// Extracts the float value corresponding to the key.
71    fn get_f64(&self, key: &str) -> Option<f64>;
72
73    /// Extracts the string corresponding to the key.
74    fn get_str(&self, key: &str) -> Option<&str>;
75
76    /// Extracts the string corresponding to the key
77    /// and represents it as `Uuid` if possible.
78    fn get_uuid(&self, key: &str) -> Option<Uuid>;
79
80    /// Extracts the string corresponding to the key
81    /// and represents it as `Date` if possible.
82    fn get_date(&self, key: &str) -> Option<Date>;
83
84    /// Extracts the string corresponding to the key
85    /// and represents it as `Time` if possible.
86    fn get_time(&self, key: &str) -> Option<Time>;
87
88    /// Extracts the string corresponding to the key
89    /// and represents it as `DateTime` if possible.
90    fn get_date_time(&self, key: &str) -> Option<DateTime>;
91
92    /// Extracts the string corresponding to the key
93    /// and represents it as `NaiveDateTime` if possible.
94    fn get_naive_date_time(&self, key: &str) -> Option<NaiveDateTime>;
95
96    /// Extracts the string corresponding to the key
97    /// and represents it as `Duration` if possible.
98    fn get_duration(&self, key: &str) -> Option<Duration>;
99
100    /// Extracts the array value corresponding to the key.
101    fn get_array(&self, key: &str) -> Option<&Vec<JsonValue>>;
102
103    /// Extracts the array value corresponding to the key and parses it as `Vec<u64>`.
104    fn get_u64_array(&self, key: &str) -> Option<Vec<u64>>;
105
106    /// Extracts the array value corresponding to the key and parses it as `Vec<i64>`.
107    fn get_i64_array(&self, key: &str) -> Option<Vec<i64>>;
108
109    /// Extracts the array value corresponding to the key and parses it as `Vec<f32>`.
110    fn get_f32_array(&self, key: &str) -> Option<Vec<f32>>;
111
112    /// Extracts the array value corresponding to the key and parses it as `Vec<f64>`.
113    fn get_f64_array(&self, key: &str) -> Option<Vec<f64>>;
114
115    /// Extracts the array value corresponding to the key and parses it as `Vec<&str>`.
116    fn get_str_array(&self, key: &str) -> Option<Vec<&str>>;
117
118    /// Extracts the array value corresponding to the key and parses it as `Vec<&Map>`.
119    fn get_map_array(&self, key: &str) -> Option<Vec<&Map>>;
120
121    /// Extracts the object value corresponding to the key.
122    fn get_object(&self, key: &str) -> Option<&Map>;
123
124    /// Extracts the populated data corresponding to the key.
125    fn get_populated(&self, key: &str) -> Option<&Map>;
126
127    /// Extracts the translated string value corresponding to the key.
128    fn get_translated(&self, key: &str) -> Option<&str>;
129
130    /// Extracts the value corresponding to the key and parses it as `bool`.
131    fn parse_bool(&self, key: &str) -> Option<Result<bool, ParseBoolError>>;
132
133    /// Extracts the value corresponding to the key and parses it as `u8`.
134    fn parse_u8(&self, key: &str) -> Option<Result<u8, ParseIntError>>;
135
136    /// Extracts the value corresponding to the key and parses it as `u16`.
137    fn parse_u16(&self, key: &str) -> Option<Result<u16, ParseIntError>>;
138
139    /// Extracts the value corresponding to the key and parses it as `u32`.
140    fn parse_u32(&self, key: &str) -> Option<Result<u32, ParseIntError>>;
141
142    /// Extracts the value corresponding to the key and parses it as `u64`.
143    fn parse_u64(&self, key: &str) -> Option<Result<u64, ParseIntError>>;
144
145    /// Extracts the value corresponding to the key and parses it as `usize`.
146    fn parse_usize(&self, key: &str) -> Option<Result<usize, ParseIntError>>;
147
148    /// Extracts the value corresponding to the key and parses it as `i8`.
149    fn parse_i8(&self, key: &str) -> Option<Result<i8, ParseIntError>>;
150
151    /// Extracts the value corresponding to the key and parses it as `i16`.
152    fn parse_i16(&self, key: &str) -> Option<Result<i16, ParseIntError>>;
153
154    /// Extracts the value corresponding to the key and parses it as `i32`.
155    fn parse_i32(&self, key: &str) -> Option<Result<i32, ParseIntError>>;
156
157    /// Extracts the value corresponding to the key and parses it as `i64`.
158    fn parse_i64(&self, key: &str) -> Option<Result<i64, ParseIntError>>;
159
160    /// Extracts the value corresponding to the key and parses it as `isize`.
161    fn parse_isize(&self, key: &str) -> Option<Result<isize, ParseIntError>>;
162
163    /// Extracts the value corresponding to the key and parses it as `f32`.
164    fn parse_f32(&self, key: &str) -> Option<Result<f32, ParseFloatError>>;
165
166    /// Extracts the value corresponding to the key and parses it as `f64`.
167    fn parse_f64(&self, key: &str) -> Option<Result<f64, ParseFloatError>>;
168
169    /// Extracts the value corresponding to the key and parses it as `Cow<'_, str>`.
170    /// If the str is empty, it also returns `None`.
171    fn parse_string(&self, key: &str) -> Option<Cow<'_, str>>;
172
173    /// Extracts the array value corresponding to the key and parses it as `Vec<T>`.
174    /// If the vec is empty, it also returns `None`.
175    fn parse_array<T: FromStr>(&self, key: &str) -> Option<Result<Vec<T>, <T as FromStr>::Err>>;
176
177    /// Extracts the array value corresponding to the key and parses it as `Vec<&str>`.
178    /// If the vec is empty, it also returns `None`.
179    fn parse_str_array(&self, key: &str) -> Option<Vec<&str>>;
180
181    /// Extracts the enum values corresponding to the key
182    /// and parses it as `Vec<i64>` or `Vec<String>`.
183    /// If the vec is empty, it also returns `None`.
184    fn parse_enum_values(&self, key: &str) -> Option<Vec<JsonValue>>;
185
186    /// Extracts the object value corresponding to the key and parses it as `Map`.
187    /// If the map is empty, it also returns `None`.
188    fn parse_object(&self, key: &str) -> Option<&Map>;
189
190    /// Extracts the string corresponding to the key and parses it as `Uuid`.
191    /// If the `Uuid` is `nil`, it also returns `None`.
192    fn parse_uuid(&self, key: &str) -> Option<Result<Uuid, uuid::Error>>;
193
194    /// Extracts the string corresponding to the key and parses it as `Decimal`.
195    fn parse_decimal(&self, key: &str) -> Option<Result<Decimal, rust_decimal::Error>>;
196
197    /// Extracts the string corresponding to the key and parses it as `Date`.
198    fn parse_date(&self, key: &str) -> Option<Result<Date, chrono::format::ParseError>>;
199
200    /// Extracts the string corresponding to the key and parses it as `Time`.
201    fn parse_time(&self, key: &str) -> Option<Result<Time, chrono::format::ParseError>>;
202
203    /// Extracts the string corresponding to the key and parses it as `DateTime`.
204    fn parse_date_time(&self, key: &str) -> Option<Result<DateTime, chrono::format::ParseError>>;
205
206    /// Extracts the string corresponding to the key and parses it as `NaiveDateTime`.
207    fn parse_naive_date_time(
208        &self,
209        key: &str,
210    ) -> Option<Result<NaiveDateTime, chrono::format::ParseError>>;
211
212    /// Extracts the string corresponding to the key and parses it as `Duration`.
213    fn parse_duration(&self, key: &str) -> Option<Result<Duration, datetime::ParseDurationError>>;
214
215    /// Extracts the string corresponding to the key and parses it as `Url`.
216    fn parse_url(&self, key: &str) -> Option<Result<Url, url::ParseError>>;
217
218    /// Extracts the string corresponding to the key and parses it as `IpAddr`.
219    fn parse_ip(&self, key: &str) -> Option<Result<IpAddr, AddrParseError>>;
220
221    /// Extracts the string corresponding to the key and parses it as `Ipv4Addr`.
222    fn parse_ipv4(&self, key: &str) -> Option<Result<Ipv4Addr, AddrParseError>>;
223
224    /// Extracts the string corresponding to the key and parses it as `Ipv6Addr`.
225    fn parse_ipv6(&self, key: &str) -> Option<Result<Ipv6Addr, AddrParseError>>;
226
227    /// Extracts the value corresponding to the key and parses it as a model `M`.
228    fn parse_model<M: Model>(&self, key: &str) -> Option<Result<M, Validation>>;
229
230    /// Looks up a value by a JSON Pointer.
231    ///
232    /// A Pointer is a Unicode string with the reference tokens separated by `/`.
233    /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`.
234    /// The addressed value is returned and if there is no such value `None` is returned.
235    fn pointer(&self, pointer: &str) -> Option<&JsonValue>;
236
237    /// Looks up a value by a JSON Pointer and returns a mutable reference to that value.
238    fn pointer_mut(&mut self, pointer: &str) -> Option<&mut JsonValue>;
239
240    /// Inserts or updates a  pair into the map.
241    /// If the map did have this key present, the value is updated and the old value is returned,
242    /// otherwise `None` is returned.
243    fn upsert(&mut self, key: impl Into<String>, value: impl Into<JsonValue>) -> Option<JsonValue>;
244
245    /// Clones values from the populated data corresponding to the key into `self`.
246    fn clone_from_populated<K: AsRef<str>>(&mut self, key: &str, fields: &[K]);
247
248    /// Extracts values from the populated data corresponding to the key and moves them to `self`.
249    fn extract_from_populated<K: AsRef<str>>(&mut self, key: &str, fields: &[K]);
250
251    /// Clones the entries corresponding to the keys.
252    fn clone_entries<K: AsRef<str>>(&mut self, keys: &[K]) -> Self;
253
254    /// Extracts the entries corresponding to the keys.
255    fn extract_entries<K: AsRef<str>>(&mut self, keys: &[K]) -> Self;
256
257    /// Removes all the entries for the keys.
258    fn remove_entries<K: AsRef<str>>(&mut self, keys: &[K]);
259
260    /// Renames all the keys to the specific case.
261    fn rename_keys(&mut self, case: Case);
262
263    /// Attempts to read the map as an instance of the model `M`.
264    fn read_as_model<M: Model>(&self) -> Result<M, Validation>;
265
266    /// Serializes the map into a string.
267    fn to_string(&self) -> String;
268
269    /// Serializes the map into a query string.
270    fn to_query_string(&self) -> String;
271
272    /// Consumes `self` and constructs an Avro record value.
273    fn into_avro_record(self) -> Record;
274
275    /// Creates a new instance with the entry.
276    fn from_entry(key: impl Into<String>, value: impl Into<JsonValue>) -> Self;
277
278    /// Creates a new instance from the entries.
279    /// If the JSON value is not an object, an empty map will be returned.
280    fn from_entries(entries: JsonValue) -> Self;
281
282    /// Creates a new instance with a single key `entry`.
283    fn data_entry(value: Map) -> Self;
284
285    /// Creates a new instance with the `entries`.
286    fn data_entries(values: Vec<Map>) -> Self;
287
288    /// Creates a new instance with a single key `item`.
289    fn data_item(value: impl Into<JsonValue>) -> Self;
290
291    /// Creates a new instance with the `items`.
292    fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Self;
293}
294
295impl JsonObjectExt for Map {
296    #[inline]
297    fn get_bool(&self, key: &str) -> Option<bool> {
298        self.get(key).and_then(|v| v.as_bool())
299    }
300
301    #[inline]
302    fn get_u8(&self, key: &str) -> Option<u8> {
303        self.get(key)
304            .and_then(|v| v.as_u64())
305            .and_then(|i| u8::try_from(i).ok())
306    }
307
308    #[inline]
309    fn get_u16(&self, key: &str) -> Option<u16> {
310        self.get(key)
311            .and_then(|v| v.as_u64())
312            .and_then(|i| u16::try_from(i).ok())
313    }
314
315    #[inline]
316    fn get_u32(&self, key: &str) -> Option<u32> {
317        self.get(key)
318            .and_then(|v| v.as_u64())
319            .and_then(|i| u32::try_from(i).ok())
320    }
321
322    #[inline]
323    fn get_u64(&self, key: &str) -> Option<u64> {
324        self.get(key).and_then(|v| v.as_u64())
325    }
326
327    #[inline]
328    fn get_usize(&self, key: &str) -> Option<usize> {
329        self.get(key)
330            .and_then(|v| v.as_u64())
331            .and_then(|i| usize::try_from(i).ok())
332    }
333
334    #[inline]
335    fn get_i8(&self, key: &str) -> Option<i8> {
336        self.get(key)
337            .and_then(|v| v.as_i64())
338            .and_then(|i| i8::try_from(i).ok())
339    }
340
341    #[inline]
342    fn get_i16(&self, key: &str) -> Option<i16> {
343        self.get(key)
344            .and_then(|v| v.as_i64())
345            .and_then(|i| i16::try_from(i).ok())
346    }
347
348    #[inline]
349    fn get_i32(&self, key: &str) -> Option<i32> {
350        self.get(key)
351            .and_then(|v| v.as_i64())
352            .and_then(|i| i32::try_from(i).ok())
353    }
354
355    #[inline]
356    fn get_i64(&self, key: &str) -> Option<i64> {
357        self.get(key).and_then(|v| v.as_i64())
358    }
359
360    #[inline]
361    fn get_isize(&self, key: &str) -> Option<isize> {
362        self.get(key)
363            .and_then(|v| v.as_i64())
364            .and_then(|i| isize::try_from(i).ok())
365    }
366
367    #[inline]
368    fn get_f32(&self, key: &str) -> Option<f32> {
369        self.get(key).and_then(|v| v.as_f64()).map(|f| f as f32)
370    }
371
372    #[inline]
373    fn get_f64(&self, key: &str) -> Option<f64> {
374        self.get(key).and_then(|v| v.as_f64())
375    }
376
377    #[inline]
378    fn get_str(&self, key: &str) -> Option<&str> {
379        self.get(key).and_then(|v| v.as_str())
380    }
381
382    #[inline]
383    fn get_uuid(&self, key: &str) -> Option<Uuid> {
384        self.get_str(key).and_then(|s| s.parse().ok())
385    }
386
387    #[inline]
388    fn get_date(&self, key: &str) -> Option<Date> {
389        self.get_str(key).and_then(|s| s.parse().ok())
390    }
391
392    #[inline]
393    fn get_time(&self, key: &str) -> Option<Time> {
394        self.get_str(key).and_then(|s| s.parse().ok())
395    }
396
397    #[inline]
398    fn get_date_time(&self, key: &str) -> Option<DateTime> {
399        self.get_str(key).and_then(|s| s.parse().ok())
400    }
401
402    #[inline]
403    fn get_naive_date_time(&self, key: &str) -> Option<NaiveDateTime> {
404        self.get_str(key).and_then(|s| s.parse().ok())
405    }
406
407    #[inline]
408    fn get_duration(&self, key: &str) -> Option<Duration> {
409        self.get_str(key)
410            .and_then(|s| datetime::parse_duration(s).ok())
411    }
412
413    #[inline]
414    fn get_array(&self, key: &str) -> Option<&Vec<JsonValue>> {
415        self.get(key).and_then(|v| v.as_array())
416    }
417
418    #[inline]
419    fn get_u64_array(&self, key: &str) -> Option<Vec<u64>> {
420        self.get_array(key)
421            .map(|values| values.iter().filter_map(|v| v.as_u64()).collect())
422    }
423
424    #[inline]
425    fn get_i64_array(&self, key: &str) -> Option<Vec<i64>> {
426        self.get_array(key)
427            .map(|values| values.iter().filter_map(|v| v.as_i64()).collect())
428    }
429
430    #[inline]
431    fn get_f32_array(&self, key: &str) -> Option<Vec<f32>> {
432        self.get_array(key).map(|values| {
433            values
434                .iter()
435                .filter_map(|v| v.as_f64().map(|f| f as f32))
436                .collect()
437        })
438    }
439
440    #[inline]
441    fn get_f64_array(&self, key: &str) -> Option<Vec<f64>> {
442        self.get_array(key)
443            .map(|values| values.iter().filter_map(|v| v.as_f64()).collect())
444    }
445
446    #[inline]
447    fn get_str_array(&self, key: &str) -> Option<Vec<&str>> {
448        self.get_array(key)
449            .map(|values| values.iter().filter_map(|v| v.as_str()).collect())
450    }
451
452    #[inline]
453    fn get_map_array(&self, key: &str) -> Option<Vec<&Map>> {
454        self.get_array(key).map(|values| {
455            values
456                .iter()
457                .filter_map(|v| v.as_object())
458                .collect::<Vec<_>>()
459        })
460    }
461
462    #[inline]
463    fn get_object(&self, key: &str) -> Option<&Map> {
464        self.get(key).and_then(|v| v.as_object())
465    }
466
467    #[inline]
468    fn get_populated(&self, key: &str) -> Option<&Map> {
469        let populated_field = [key, "_populated"].concat();
470        self.get_object(&populated_field)
471    }
472
473    #[inline]
474    fn get_translated(&self, key: &str) -> Option<&str> {
475        let translated_field = [key, "_translated"].concat();
476        self.get_str(&translated_field)
477    }
478
479    fn parse_bool(&self, key: &str) -> Option<Result<bool, ParseBoolError>> {
480        let value = self.get(key);
481        value
482            .and_then(|v| v.as_bool())
483            .map(Ok)
484            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
485    }
486
487    fn parse_u8(&self, key: &str) -> Option<Result<u8, ParseIntError>> {
488        let value = self.get(key);
489        value
490            .and_then(|v| v.as_u64())
491            .and_then(|i| u8::try_from(i).ok())
492            .map(Ok)
493            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
494    }
495
496    fn parse_u16(&self, key: &str) -> Option<Result<u16, ParseIntError>> {
497        let value = self.get(key);
498        value
499            .and_then(|v| v.as_u64())
500            .and_then(|i| u16::try_from(i).ok())
501            .map(Ok)
502            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
503    }
504
505    fn parse_u32(&self, key: &str) -> Option<Result<u32, ParseIntError>> {
506        let value = self.get(key);
507        value
508            .and_then(|v| v.as_u64())
509            .and_then(|i| u32::try_from(i).ok())
510            .map(Ok)
511            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
512    }
513
514    fn parse_u64(&self, key: &str) -> Option<Result<u64, ParseIntError>> {
515        let value = self.get(key);
516        value
517            .and_then(|v| v.as_u64())
518            .map(Ok)
519            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
520    }
521
522    fn parse_usize(&self, key: &str) -> Option<Result<usize, ParseIntError>> {
523        let value = self.get(key);
524        value
525            .and_then(|v| v.as_u64())
526            .and_then(|i| usize::try_from(i).ok())
527            .map(Ok)
528            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
529    }
530
531    fn parse_i8(&self, key: &str) -> Option<Result<i8, ParseIntError>> {
532        let value = self.get(key);
533        value
534            .and_then(|v| v.as_i64())
535            .and_then(|i| i8::try_from(i).ok())
536            .map(Ok)
537            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
538    }
539
540    fn parse_i16(&self, key: &str) -> Option<Result<i16, ParseIntError>> {
541        let value = self.get(key);
542        value
543            .and_then(|v| v.as_i64())
544            .and_then(|i| i16::try_from(i).ok())
545            .map(Ok)
546            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
547    }
548
549    fn parse_i32(&self, key: &str) -> Option<Result<i32, ParseIntError>> {
550        let value = self.get(key);
551        value
552            .and_then(|v| v.as_i64())
553            .and_then(|i| i32::try_from(i).ok())
554            .map(Ok)
555            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
556    }
557
558    fn parse_i64(&self, key: &str) -> Option<Result<i64, ParseIntError>> {
559        let value = self.get(key);
560        value
561            .and_then(|v| v.as_i64())
562            .map(Ok)
563            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
564    }
565
566    fn parse_isize(&self, key: &str) -> Option<Result<isize, ParseIntError>> {
567        let value = self.get(key);
568        value
569            .and_then(|v| v.as_i64())
570            .and_then(|i| isize::try_from(i).ok())
571            .map(Ok)
572            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
573    }
574
575    fn parse_f32(&self, key: &str) -> Option<Result<f32, ParseFloatError>> {
576        let value = self.get(key);
577        value
578            .and_then(|v| v.as_f64())
579            .map(|f| Ok(f as f32))
580            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
581    }
582
583    fn parse_f64(&self, key: &str) -> Option<Result<f64, ParseFloatError>> {
584        let value = self.get(key);
585        value
586            .and_then(|v| v.as_f64())
587            .map(Ok)
588            .or_else(|| value.and_then(|v| v.as_str()).map(|s| s.parse()))
589    }
590
591    fn parse_string(&self, key: &str) -> Option<Cow<'_, str>> {
592        self.get(key)
593            .and_then(|v| {
594                v.as_str()
595                    .map(|s| Cow::Borrowed(s.trim()))
596                    .or_else(|| Some(v.to_string().into()))
597            })
598            .filter(|s| !s.is_empty())
599    }
600
601    fn parse_array<T: FromStr>(&self, key: &str) -> Option<Result<Vec<T>, <T as FromStr>::Err>> {
602        let values = match self.get(key)? {
603            JsonValue::String(s) => helper::parse_str_array(s, ',')
604                .into_iter()
605                .filter_map(|s| (!s.is_empty()).then_some(Cow::Borrowed(s)))
606                .collect::<Vec<_>>(),
607            JsonValue::Array(vec) => vec
608                .iter()
609                .filter(|v| !v.is_null())
610                .filter_map(|v| v.parse_string())
611                .collect::<Vec<_>>(),
612            _ => return None,
613        };
614        let mut vec = Vec::with_capacity(values.len());
615        for value in values {
616            match value.parse() {
617                Ok(v) => vec.push(v),
618                Err(err) => return Some(Err(err)),
619            }
620        }
621        (!vec.is_empty()).then_some(Ok(vec))
622    }
623
624    fn parse_str_array(&self, key: &str) -> Option<Vec<&str>> {
625        self.get(key)
626            .and_then(|v| match v {
627                JsonValue::String(s) => Some(helper::parse_str_array(s, ',')),
628                JsonValue::Array(v) => Some(v.iter().filter_map(|v| v.as_str()).collect()),
629                _ => None,
630            })
631            .and_then(|values| {
632                let vec = values.iter().map(|s| s.trim()).collect::<Vec<_>>();
633                (!vec.is_empty()).then_some(vec)
634            })
635    }
636
637    fn parse_enum_values(&self, key: &str) -> Option<Vec<JsonValue>> {
638        self.get(key)
639            .and_then(|v| match v {
640                JsonValue::String(s) => {
641                    let values = helper::parse_str_array(s, '|');
642                    let vec = values
643                        .iter()
644                        .map(|s| {
645                            let s = s.trim();
646                            if let Ok(integer) = s.parse::<i64>() {
647                                JsonValue::Number(integer.into())
648                            } else {
649                                JsonValue::String(s.to_owned())
650                            }
651                        })
652                        .collect::<Vec<_>>();
653                    Some(vec)
654                }
655                JsonValue::Array(vec) => Some(vec.to_owned()),
656                _ => None,
657            })
658            .filter(|vec| !vec.is_empty())
659    }
660
661    #[inline]
662    fn parse_object(&self, key: &str) -> Option<&Map> {
663        self.get_object(key).filter(|o| !o.is_empty())
664    }
665
666    fn parse_uuid(&self, key: &str) -> Option<Result<Uuid, uuid::Error>> {
667        self.get_str(key)
668            .map(|s| s.trim_start_matches("urn:uuid:"))
669            .filter(|s| !s.chars().all(|c| c == '0' || c == '-'))
670            .map(|s| s.parse())
671    }
672
673    #[inline]
674    fn parse_decimal(&self, key: &str) -> Option<Result<Decimal, rust_decimal::Error>> {
675        self.get_str(key).map(|s| s.parse())
676    }
677
678    #[inline]
679    fn parse_date(&self, key: &str) -> Option<Result<Date, chrono::format::ParseError>> {
680        self.get_str(key).map(|s| s.parse())
681    }
682
683    #[inline]
684    fn parse_time(&self, key: &str) -> Option<Result<Time, chrono::format::ParseError>> {
685        self.get_str(key).map(|s| s.parse())
686    }
687
688    #[inline]
689    fn parse_date_time(&self, key: &str) -> Option<Result<DateTime, chrono::format::ParseError>> {
690        self.get_str(key).map(|s| s.parse())
691    }
692
693    #[inline]
694    fn parse_naive_date_time(
695        &self,
696        key: &str,
697    ) -> Option<Result<NaiveDateTime, chrono::format::ParseError>> {
698        self.get_str(key).map(|s| s.parse())
699    }
700
701    #[inline]
702    fn parse_duration(&self, key: &str) -> Option<Result<Duration, datetime::ParseDurationError>> {
703        self.get_str(key).map(datetime::parse_duration)
704    }
705
706    #[inline]
707    fn parse_url(&self, key: &str) -> Option<Result<Url, url::ParseError>> {
708        self.get_str(key).map(|s| s.parse())
709    }
710
711    #[inline]
712    fn parse_ip(&self, key: &str) -> Option<Result<IpAddr, AddrParseError>> {
713        self.get_str(key).map(|s| s.parse())
714    }
715
716    #[inline]
717    fn parse_ipv4(&self, key: &str) -> Option<Result<Ipv4Addr, AddrParseError>> {
718        self.get_str(key).map(|s| s.parse())
719    }
720
721    #[inline]
722    fn parse_ipv6(&self, key: &str) -> Option<Result<Ipv6Addr, AddrParseError>> {
723        self.get_str(key).map(|s| s.parse())
724    }
725
726    fn parse_model<M: Model>(&self, key: &str) -> Option<Result<M, Validation>> {
727        self.get_object(key).map(|data| {
728            let mut model = M::new();
729            let validation = model.read_map(data);
730            if validation.is_success() {
731                Ok(model)
732            } else {
733                Err(validation)
734            }
735        })
736    }
737
738    fn pointer(&self, pointer: &str) -> Option<&JsonValue> {
739        let path = pointer.strip_prefix('/')?;
740        if let Some(position) = path.find('/') {
741            let (key, pointer) = path.split_at(position);
742            self.get(key)?.pointer(pointer)
743        } else {
744            self.get(path)
745        }
746    }
747
748    fn pointer_mut(&mut self, pointer: &str) -> Option<&mut JsonValue> {
749        let path = pointer.strip_prefix('/')?;
750        if let Some(position) = path.find('/') {
751            let (key, pointer) = path.split_at(position);
752            self.get_mut(key)?.pointer_mut(pointer)
753        } else {
754            self.get_mut(path)
755        }
756    }
757
758    #[inline]
759    fn upsert(&mut self, key: impl Into<String>, value: impl Into<JsonValue>) -> Option<JsonValue> {
760        self.insert(key.into(), value.into())
761    }
762
763    fn clone_from_populated<K: AsRef<str>>(&mut self, key: &str, fields: &[K]) {
764        let mut object = Map::new();
765        if let Some(map) = self.get_populated(key) {
766            for field in fields {
767                let field = field.as_ref();
768                if let Some(value) = map.get(field) {
769                    object.insert(field.to_owned(), value.to_owned());
770                }
771            }
772        }
773        self.append(&mut object);
774    }
775
776    fn extract_from_populated<K: AsRef<str>>(&mut self, key: &str, fields: &[K]) {
777        let mut object = Map::new();
778        let populated_field = [key, "_populated"].concat();
779        if let Some(&mut ref mut map) = self
780            .get_mut(&populated_field)
781            .and_then(|v| v.as_object_mut())
782        {
783            for field in fields {
784                let field = field.as_ref();
785                if let Some(value) = map.remove(field) {
786                    object.insert(field.to_owned(), value);
787                }
788            }
789        }
790        self.append(&mut object);
791    }
792
793    #[inline]
794    fn clone_entries<K: AsRef<str>>(&mut self, keys: &[K]) -> Self {
795        let mut map = Map::new();
796        for key in keys {
797            let field = key.as_ref();
798            if let Some(value) = self.get(field) {
799                map.insert(field.to_owned(), value.to_owned());
800            }
801        }
802        map
803    }
804
805    #[inline]
806    fn extract_entries<K: AsRef<str>>(&mut self, keys: &[K]) -> Self {
807        let mut map = Map::new();
808        for key in keys {
809            let field = key.as_ref();
810            if let Some(value) = self.remove(field) {
811                map.insert(field.to_owned(), value);
812            }
813        }
814        map
815    }
816
817    #[inline]
818    fn remove_entries<K: AsRef<str>>(&mut self, keys: &[K]) {
819        for key in keys {
820            self.remove(key.as_ref());
821        }
822    }
823
824    #[inline]
825    fn rename_keys(&mut self, case: Case) {
826        for (key, value) in mem::take(self) {
827            self.insert(key.to_case(case), value);
828        }
829    }
830
831    fn read_as_model<M: Model>(&self) -> Result<M, Validation> {
832        let mut model = M::new();
833        let validation = model.read_map(self);
834        if validation.is_success() {
835            Ok(model)
836        } else {
837            Err(validation)
838        }
839    }
840
841    #[inline]
842    fn to_string(&self) -> String {
843        serde_json::to_string(&self).unwrap_or_default()
844    }
845
846    #[inline]
847    fn to_query_string(&self) -> String {
848        serde_qs::to_string(&self).unwrap_or_default()
849    }
850
851    fn into_avro_record(self) -> Record {
852        let mut record = Record::with_capacity(self.len());
853        for (field, value) in self.into_iter() {
854            record.push((field, value.into()));
855        }
856        record
857    }
858
859    #[inline]
860    fn from_entry(key: impl Into<String>, value: impl Into<JsonValue>) -> Self {
861        let mut map = Map::new();
862        map.insert(key.into(), value.into());
863        map
864    }
865
866    #[inline]
867    fn from_entries(entries: JsonValue) -> Self {
868        if let JsonValue::Object(map) = entries {
869            map
870        } else {
871            Map::new()
872        }
873    }
874
875    #[inline]
876    fn data_entry(value: Map) -> Self {
877        let mut map = Map::new();
878        map.insert("entry".to_owned(), value.into());
879        map
880    }
881
882    #[inline]
883    fn data_entries(values: Vec<Map>) -> Self {
884        let mut map = Map::new();
885        map.insert("num_entries".to_owned(), values.len().into());
886        map.insert("entries".to_owned(), values.into());
887        map
888    }
889
890    #[inline]
891    fn data_item(value: impl Into<JsonValue>) -> Self {
892        let mut map = Map::new();
893        map.insert("item".to_owned(), value.into());
894        map
895    }
896
897    #[inline]
898    fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Self {
899        let mut map = Map::new();
900        map.insert("num_items".to_owned(), values.len().into());
901        map.insert("items".to_owned(), values.into());
902        map
903    }
904}
905
906#[cfg(test)]
907mod tests {
908    use crate::{
909        Map,
910        extension::{JsonObjectExt, JsonValueExt},
911    };
912
913    #[test]
914    fn it_parses_str_array() {
915        let mut map = Map::new();
916        map.upsert("roles", vec!["admin", "", "worker"]);
917
918        assert_eq!(
919            map.get_str_array("roles"),
920            Some(vec!["admin", "", "worker"])
921        );
922        assert_eq!(
923            map.parse_str_array("roles"),
924            Some(vec!["admin", "", "worker"])
925        );
926        assert_eq!(
927            map.parse_array::<String>("roles"),
928            Some(Ok(vec!["admin".to_owned(), "worker".to_owned()]))
929        );
930    }
931
932    #[test]
933    fn it_lookups_json_value() {
934        let mut map = Map::new();
935        map.upsert("entries", vec![Map::from_entry("name", "alice")]);
936        map.upsert("total", 1);
937
938        assert_eq!(map.pointer("total"), None);
939        assert_eq!(map.pointer("/total").and_then(|v| v.as_usize()), Some(1));
940        assert_eq!(
941            map.pointer("/entries/0/name").and_then(|v| v.as_str()),
942            Some("alice")
943        );
944    }
945}