simd_json/value/tape/
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
131
132
133
use super::Value;
use crate::Node;

#[derive(Clone, Copy)]
/// Wrapper around the tape that allows interacting with it via a `Array`-like API.
pub struct Array<'tape, 'input>(pub(super) &'tape [Node<'input>]);

pub struct Iter<'tape, 'input>(&'tape [Node<'input>]);

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

    fn next(&mut self) -> Option<Self::Item> {
        let (head, tail) = self.0.split_at(self.0.first()?.count());
        self.0 = tail;
        Some(Value(head))
    }
}

// value_trait::Array for
impl<'tape, 'input> Array<'tape, 'input>
where
    'input: 'tape,
{
    /// 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(&self, mut idx: usize) -> Option<Value<'tape, 'input>> {
        let mut offset = 1;
        while idx > 0 {
            offset += self.0.get(offset)?.count();
            idx -= 1;
        }
        let count = self.0.get(offset)?.count();
        Some(Value(&self.0[offset..offset + count]))
    }

    /// Iterates over the values paris
    #[must_use]
    pub fn iter<'i>(&'i self) -> Iter<'tape, 'input> {
        Iter(&self.0[1..])
    }

    /// Number of key/value pairs
    /// # Panics
    /// if the tape is not an array
    #[must_use]
    pub fn len(&self) -> usize {
        if let Some(Node::Array { len, .. }) = self.0.first() {
            *len
        } else {
            panic!("invalid tape array")
        }
    }
    /// Returns if the array is empty
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

impl<'tape, 'input> IntoIterator for &Array<'tape, 'input> {
    type IntoIter = Iter<'tape, 'input>;
    type Item = Value<'tape, 'input>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

#[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(())
    }
}