simdjson_rust/dom/
array.rs1use std::{marker::PhantomData, ptr::NonNull};
2
3use simdjson_sys as ffi;
4
5use super::{document::Document, element::Element};
6use crate::{
7 macros::{impl_drop, map_ptr_result},
8 Result,
9};
10
11pub struct Array<'a> {
12 ptr: NonNull<ffi::SJ_DOM_array>,
13 _doc: PhantomData<&'a Document>,
14}
15
16impl<'a> Array<'a> {
17 pub fn new(ptr: NonNull<ffi::SJ_DOM_array>) -> Self {
18 Self {
19 ptr,
20 _doc: PhantomData,
21 }
22 }
23
24 pub fn iter(&self) -> ArrayIter {
25 let begin = unsafe { NonNull::new_unchecked(ffi::SJ_DOM_array_begin(self.ptr.as_ptr())) };
26 let end = unsafe { NonNull::new_unchecked(ffi::SJ_DOM_array_end(self.ptr.as_ptr())) };
27 ArrayIter::new(begin, end)
28 }
29
30 pub fn size(&self) -> usize {
31 unsafe { ffi::SJ_DOM_array_size(self.ptr.as_ptr()) }
32 }
33
34 pub fn number_of_slots(&self) -> usize {
35 unsafe { ffi::SJ_DOM_array_number_of_slots(self.ptr.as_ptr()) }
36 }
37
38 pub fn at_pointer(&self, json_pointer: &str) -> Result<Element<'a>> {
39 map_ptr_result!(ffi::SJ_DOM_array_at_pointer(
40 self.ptr.as_ptr(),
41 json_pointer.as_ptr().cast(),
42 json_pointer.len()
43 ))
44 .map(Element::new)
45 }
46
47 pub fn at(&self, index: usize) -> Result<Element<'a>> {
48 map_ptr_result!(ffi::SJ_DOM_array_at(self.ptr.as_ptr(), index)).map(Element::new)
49 }
50}
51
52impl_drop!(Array<'a>, ffi::SJ_DOM_array_free);
53
54pub struct ArrayIter<'a> {
55 begin: NonNull<ffi::SJ_DOM_array_iterator>,
56 end: NonNull<ffi::SJ_DOM_array_iterator>,
57 running: bool,
58 _doc: PhantomData<&'a Document>,
59}
60
61impl<'a> ArrayIter<'a> {
62 pub fn new(
63 begin: NonNull<ffi::SJ_DOM_array_iterator>,
64 end: NonNull<ffi::SJ_DOM_array_iterator>,
65 ) -> Self {
66 Self {
67 begin,
68 end,
69 running: false,
70 _doc: PhantomData,
71 }
72 }
73
74 pub fn get(&self) -> Element<'a> {
75 let ptr = unsafe { ffi::SJ_DOM_array_iterator_get(self.begin.as_ptr()) };
76 Element::new(unsafe { NonNull::new_unchecked(ptr) })
77 }
78
79 pub fn step(&mut self) {
80 unsafe { ffi::SJ_DOM_array_iterator_step(self.begin.as_ptr()) }
81 }
82
83 pub fn not_equal(&self) -> bool {
84 unsafe { ffi::SJ_DOM_array_iterator_not_equal(self.begin.as_ptr(), self.end.as_ptr()) }
85 }
86}
87
88impl<'a> Drop for ArrayIter<'a> {
89 fn drop(&mut self) {
90 unsafe {
91 ffi::SJ_DOM_array_iterator_free(self.begin.as_ptr());
92 ffi::SJ_DOM_array_iterator_free(self.end.as_ptr());
93 }
94 }
95}
96
97impl<'a> Iterator for ArrayIter<'a> {
98 type Item = Element<'a>;
99
100 fn next(&mut self) -> Option<Self::Item> {
101 if self.running {
102 self.step();
103 }
104
105 if self.not_equal() {
106 self.running = true;
107 Some(self.get())
108 } else {
109 None
110 }
111 }
112}