simd_json/value/lazy/
array.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::borrow::Cow;

use super::Value;
use crate::{borrowed, tape};

#[derive(Clone)]
/// Wrapper around the tape that allows interacting with it via a `Array`-like API.
pub enum Array<'borrow, 'tape, 'input> {
    /// Tape variant
    Tape(tape::Array<'tape, 'input>),
    /// Value variant
    Value(&'borrow borrowed::Array<'input>),
}

pub enum ArrayIter<'borrow, 'tape, 'input> {
    Tape(tape::array::Iter<'tape, 'input>),
    Value(std::slice::Iter<'borrow, borrowed::Value<'input>>),
}

impl<'borrow, 'tape, 'input> Iterator for ArrayIter<'borrow, 'tape, 'input> {
    type Item = Value<'borrow, 'tape, 'input>;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            ArrayIter::Tape(t) => t.next().map(Value::Tape),
            ArrayIter::Value(v) => v.next().map(Cow::Borrowed).map(Value::Value),
        }
    }
}

// value_trait::Array for
impl<'borrow, 'tape, 'input> Array<'borrow, 'tape, 'input> {
    /// Gets a ref to a value based on n index, returns `None` if the
    /// current Value isn't an Array or doesn't contain the index
    /// it was asked for.
    #[must_use]
    pub fn get<'a>(&'a self, idx: usize) -> Option<Value<'a, 'tape, 'input>> {
        match self {
            Array::Tape(t) => t.get(idx).map(Value::Tape),
            Array::Value(v) => v.get(idx).map(Cow::Borrowed).map(Value::Value),
        }
    }
    /// Iterates over the values paris
    #[allow(clippy::pedantic)] // we want into_iter_without_iter but that lint doesn't exist in older clippy
    #[must_use]
    pub fn iter<'i>(&'i self) -> ArrayIter<'i, 'tape, 'input> {
        match self {
            Array::Tape(t) => ArrayIter::Tape(t.iter()),
            Array::Value(v) => ArrayIter::Value(v.iter()),
        }
    }

    /// Number of key/value pairs
    #[must_use]
    pub fn len(&self) -> usize {
        match self {
            Array::Tape(t) => t.len(),
            Array::Value(v) => v.len(),
        }
    }
    /// Returns if the array is empty
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

#[cfg(test)]
mod test {
    use crate::to_tape;
    use value_trait::base::ValueAsScalar;

    #[test]
    fn get_ints() -> crate::Result<()> {
        let mut input = b"[1,2,3,4]".to_vec();
        let t = to_tape(input.as_mut_slice())?;
        let v = t.as_value();
        let a = v.as_array().expect("is an array");
        assert_eq!(a.get(0).and_then(|v| v.as_u64()), Some(1));
        assert_eq!(a.get(1).and_then(|v| v.as_u64()), Some(2));
        assert_eq!(a.get(2).and_then(|v| v.as_u64()), Some(3));
        assert_eq!(a.get(3).and_then(|v| v.as_u64()), Some(4));
        assert_eq!(a.get(4), None);
        Ok(())
    }

    #[test]
    fn get_nested() -> crate::Result<()> {
        let mut input = b"[1,[2,3],4]".to_vec();
        let t = to_tape(input.as_mut_slice())?;
        let v = t.as_value();
        let a = v.as_array().expect("is an array");
        assert_eq!(a.get(0).and_then(|v| v.as_u64()), Some(1));
        let a1 = a.get(1).expect("has first element");
        let a2 = a1.as_array().expect("is an array");
        assert_eq!(a2.get(0).and_then(|v| v.as_u64()), Some(2));
        assert_eq!(a2.get(1).and_then(|v| v.as_u64()), Some(3));
        assert_eq!(a.get(2).and_then(|v| v.as_u64()), Some(4));
        assert_eq!(a.get(3), None);
        Ok(())
    }

    #[test]
    fn iter() -> crate::Result<()> {
        let mut input = b"[1,2,3,4]".to_vec();
        let t = to_tape(input.as_mut_slice())?;
        let v = t.as_value();
        let a = v.as_array().expect("is an array");
        let v = a
            .iter()
            .map(|v| v.as_u8().expect("integer"))
            .collect::<Vec<_>>();

        assert_eq!(v, vec![1, 2, 3, 4]);

        Ok(())
    }
    #[test]
    fn iter_container() -> crate::Result<()> {
        let mut input = b"[1,[2,3],4]".to_vec();
        let t = to_tape(input.as_mut_slice())?;
        let v = t.as_value();
        let a = v.as_array().expect("is an array");
        let v = a.iter().map(|v| v.as_u8()).collect::<Vec<_>>();

        assert_eq!(v, vec![Some(1), None, Some(4)]);

        Ok(())
    }
}