simdjson_rust/dom/
object.rs1use 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);