simdjson_rust/dom/
array.rs

1use 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}