simdjson_rust/dom/
object.rs

1use std::{marker::PhantomData, ptr::NonNull};
2
3use simdjson_sys as ffi;
4
5use super::{document::Document, Element};
6use crate::{macros::impl_drop, utils::string_view_struct_to_str};
7
8pub struct Object<'a> {
9    ptr: NonNull<ffi::SJ_DOM_object>,
10    _doc: PhantomData<&'a Document>,
11}
12
13impl<'a> Object<'a> {
14    pub fn new(ptr: NonNull<ffi::SJ_DOM_object>) -> Self {
15        Self {
16            ptr,
17            _doc: PhantomData,
18        }
19    }
20}
21
22pub struct ObjectIter<'a> {
23    begin: NonNull<ffi::SJ_DOM_object_iterator>,
24    end: NonNull<ffi::SJ_DOM_object_iterator>,
25    running: bool,
26    _doc: PhantomData<&'a Document>,
27}
28
29impl<'a> ObjectIter<'a> {
30    pub fn new(
31        begin: NonNull<ffi::SJ_DOM_object_iterator>,
32        end: NonNull<ffi::SJ_DOM_object_iterator>,
33    ) -> Self {
34        Self {
35            begin,
36            end,
37            running: false,
38            _doc: PhantomData,
39        }
40    }
41
42    pub fn get(&self) -> (&'a str, Element<'a>) {
43        let kv = unsafe { ffi::SJ_DOM_object_iterator_get(self.begin.as_ptr()) };
44        let key = string_view_struct_to_str(kv.key);
45        let value = Element::new(unsafe { NonNull::new_unchecked(kv.value) });
46        (key, value)
47    }
48
49    pub fn step(&mut self) {
50        unsafe { ffi::SJ_DOM_object_iterator_step(self.begin.as_ptr()) }
51    }
52
53    pub fn not_equal(&self) -> bool {
54        unsafe { ffi::SJ_DOM_object_iterator_not_equal(self.begin.as_ptr(), self.end.as_ptr()) }
55    }
56}
57
58impl<'a> Drop for ObjectIter<'a> {
59    fn drop(&mut self) {
60        unsafe {
61            ffi::SJ_DOM_object_iterator_free(self.begin.as_ptr());
62            ffi::SJ_DOM_object_iterator_free(self.end.as_ptr());
63        }
64    }
65}
66
67impl<'a> Iterator for ObjectIter<'a> {
68    type Item = (&'a str, Element<'a>);
69
70    fn next(&mut self) -> Option<Self::Item> {
71        if self.running {
72            self.step();
73        }
74
75        if self.not_equal() {
76            self.running = true;
77            Some(self.get())
78        } else {
79            None
80        }
81    }
82}
83
84impl_drop!(Object<'a>, ffi::SJ_DOM_object_free);