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}