simdjson_rust/ondemand/
array_iterator.rs1use 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 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}