serde_json_lodash/array/nth.rs
1use crate::lib::{json, Value};
2
3/// See lodash [nth](https://lodash.com/docs/#nth)
4pub fn nth(v: Value, n: isize) -> Value {
5 match v {
6 Value::Null => json!(null),
7 Value::Bool(_) => json!(null),
8 Value::Number(_) => json!(null),
9 Value::String(s) => {
10 if s.is_empty() {
11 return json!(null);
12 }
13 let chars = s.chars();
14 let nn = {
15 if n < 0 {
16 let nn = (chars.count() as isize) + n;
17 if nn < 0 {
18 return json!(null);
19 }
20 nn
21 } else {
22 n
23 }
24 };
25 match s.chars().nth(nn as usize) {
26 Some(v) => json!(v),
27 None => json!(null),
28 }
29 }
30 Value::Array(vec) => {
31 if vec.is_empty() {
32 return json!(null);
33 }
34 let nn = {
35 if n < 0 {
36 let nn = (vec.len() as isize) + n;
37 if nn < 0 {
38 return json!(null);
39 }
40 nn
41 } else {
42 n
43 }
44 };
45 match vec.get(nn as usize) {
46 Some(v) => v.clone(),
47 None => json!(null),
48 }
49 }
50 Value::Object(_) => json!(null),
51 }
52}
53
54/// Based on [nth()]
55///
56/// Examples:
57///
58/// ```rust
59/// #[macro_use] extern crate serde_json_lodash;
60/// use serde_json::json;
61/// let array = json!(['a', 'b', 'c', 'd']);
62/// assert_eq!(
63/// nth!(array.clone(), 1),
64/// json!('b')
65/// );
66/// assert_eq!(
67/// nth!(array.clone(), -2),
68/// json!('c')
69/// );
70/// ```
71///
72/// More examples:
73///
74/// ```rust
75/// # #[macro_use] extern crate serde_json_lodash;
76/// # use serde_json::json;
77/// assert_eq!(nth!(), json!(null));
78/// assert_eq!(nth!(json!(null)), json!(null));
79/// assert_eq!(nth!(json!(false)), json!(null));
80/// assert_eq!(nth!(json!(true)), json!(null));
81/// assert_eq!(nth!(json!(0)), json!(null));
82/// assert_eq!(nth!(json!("")), json!(null));
83/// assert_eq!(nth!(json!("ab")), json!("a"));
84/// assert_eq!(nth!(json!("冬至")), json!("冬"));
85/// assert_eq!(nth!(json!("夏至"), -1), json!("至"));
86/// assert_eq!(nth!(json!("春分"), -3), json!(null));
87/// assert_eq!(nth!(json!("秋分"), 2), json!(null));
88/// assert_eq!(nth!(json!([])), json!(null));
89/// assert_eq!(nth!(json!({})), json!(null));
90/// ```
91#[macro_export]
92macro_rules! nth {
93 () => {
94 json!(null)
95 };
96 ($a:expr $(,)*) => {
97 $crate::nth($a, 0)
98 };
99 ($a:expr, $b:expr $(,)*) => {
100 $crate::nth($a, $b)
101 };
102 ($a:expr, $b:expr, $($rest:tt)*) => {
103 $crate::nth($a, $b)
104 };
105}