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