simdjson_rust/ondemand/
array_iterator.rs

1use std::{marker::PhantomData, ptr::NonNull};
2
3use simdjson_sys as ffi;
4
5use super::{document::Document, value::Value};
6use crate::{error::Result, macros::map_result};
7
8pub struct ArrayIterator<'a> {
9    begin: NonNull<ffi::SJ_OD_array_iterator>,
10    end: NonNull<ffi::SJ_OD_array_iterator>,
11    running: bool,
12    _doc: PhantomData<&'a mut Document<'a, 'a>>,
13}
14
15impl<'a> ArrayIterator<'a> {
16    pub fn new(
17        begin: NonNull<ffi::SJ_OD_array_iterator>,
18        end: NonNull<ffi::SJ_OD_array_iterator>,
19    ) -> Self {
20        Self {
21            begin,
22            end,
23            running: false,
24            _doc: PhantomData,
25        }
26    }
27
28    pub fn get(&mut self) -> Result<Value<'a>> {
29        map_result!(
30            ffi::SJ_OD_array_iterator_get(self.begin.as_mut()),
31            ffi::SJ_OD_value_result_error,
32            ffi::SJ_OD_value_result_value_unsafe
33        )
34        .map(Value::new)
35    }
36
37    pub fn not_equal(&self) -> bool {
38        unsafe { ffi::SJ_OD_array_iterator_not_equal(self.begin.as_ref(), self.end.as_ref()) }
39    }
40
41    pub fn step(&mut self) {
42        unsafe { ffi::SJ_OD_array_iterator_step(self.begin.as_mut()) }
43    }
44}
45
46impl<'a> Drop for ArrayIterator<'a> {
47    fn drop(&mut self) {
48        unsafe {
49            ffi::SJ_OD_array_iterator_free(self.begin.as_mut());
50            ffi::SJ_OD_array_iterator_free(self.end.as_mut());
51        }
52    }
53}
54
55impl<'a> Iterator for ArrayIterator<'a> {
56    type Item = Result<Value<'a>>;
57
58    fn next(&mut self) -> Option<Self::Item> {
59        if self.running {
60            self.step();
61        }
62
63        if self.not_equal() {
64            self.running = true;
65            Some(self.get())
66        } else {
67            self.running = false;
68            None
69        }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use crate::{ondemand::parser::Parser, padded_string::make_padded_string};
76
77    #[test]
78    fn test_iter() {
79        let mut parser = Parser::default();
80        let ps = make_padded_string("[1,2,3]");
81        let mut doc = parser.iterate(&ps).unwrap();
82        // drop(ps);
83        let mut arr = doc.get_array().unwrap();
84        for (v, num) in arr.iter().unwrap().zip([1u64, 2, 3]) {
85            let res = v.unwrap().get_uint64().unwrap();
86            assert_eq!(res, num);
87        }
88    }
89}