simdjson_rust/dom/
document_stream.rs

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