simdjson_rust/ondemand/
object_iterator.rs

1use std::{marker::PhantomData, ptr::NonNull};
2
3use simdjson_sys as ffi;
4
5use super::{document::Document, field::Field};
6use crate::{error::Result, macros::map_result};
7
8pub struct ObjectIterator<'a> {
9    begin: NonNull<ffi::SJ_OD_object_iterator>,
10    end: NonNull<ffi::SJ_OD_object_iterator>,
11    running: bool,
12    _doc: PhantomData<&'a mut Document<'a, 'a>>,
13}
14
15impl<'a> ObjectIterator<'a> {
16    pub fn new(
17        begin: NonNull<ffi::SJ_OD_object_iterator>,
18        end: NonNull<ffi::SJ_OD_object_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<Field<'a>> {
29        map_result!(
30            ffi::SJ_OD_object_iterator_get(self.begin.as_mut()),
31            ffi::SJ_OD_field_result_error,
32            ffi::SJ_OD_field_result_value_unsafe
33        )
34        .map(Field::new)
35    }
36
37    pub fn not_equal(&self) -> bool {
38        unsafe { ffi::SJ_OD_object_iterator_not_equal(self.begin.as_ref(), self.end.as_ref()) }
39    }
40
41    pub fn step(&mut self) {
42        unsafe { ffi::SJ_OD_object_iterator_step(self.begin.as_mut()) }
43    }
44}
45
46impl<'a> Drop for ObjectIterator<'a> {
47    fn drop(&mut self) {
48        unsafe {
49            ffi::SJ_OD_object_iterator_free(self.begin.as_mut());
50            ffi::SJ_OD_object_iterator_free(self.end.as_mut());
51        }
52    }
53}
54
55impl<'a> Iterator for ObjectIterator<'a> {
56    type Item = Result<Field<'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}