Skip to main content

json_event_parser_blocks/
skipper.rs

1use json_event_parser::JsonEvent;
2use std::fmt::Debug;
3
4#[derive(Copy, Clone, Eq, PartialEq, Debug, thiserror::Error)]
5pub enum SkipError {
6    #[error("Skip already done")]
7    SkipAlreadyDone,
8    #[error("Stack is empty (trying to skip after done?)")]
9    StackEmpty,
10    #[error("Nested object key")]
11    NestedObjectKey,
12    #[error("Eof")]
13    Eof,
14}
15
16#[derive(Copy, Clone)]
17pub struct Skipper {
18    has_skipped_value: bool,
19    depth: usize,
20}
21
22impl Default for Skipper {
23    #[inline]
24    fn default() -> Self {
25        Skipper::new()
26    }
27}
28
29impl Skipper {
30    #[inline]
31    #[doc = "create new Skipper instance"]
32    pub const fn new() -> Self {
33        Self {
34            has_skipped_value: false,
35            depth: 0,
36        }
37    }
38
39    #[inline]
40    #[doc = "in skipping state (between object/array, or just start without any value skipped)"]
41    pub fn skipping(&self) -> bool {
42        !self.has_skipped_value || self.depth > 0
43    }
44
45    #[doc = "reset to init state, for reuse. (create new one is cheap, this is not necessary)"]
46    pub fn reset(&mut self) {
47        self.has_skipped_value = false;
48        self.depth = 0;
49    }
50
51    #[doc = "feed new event to Skipper, return `skipping()`."]
52    pub fn on_event(&mut self, event: &JsonEvent<'_>) -> Result<bool, SkipError> {
53        if !self.skipping() {
54            return Err(SkipError::SkipAlreadyDone);
55        }
56
57        match event {
58            JsonEvent::String(_)
59            | JsonEvent::Number(_)
60            | JsonEvent::Boolean(_)
61            | JsonEvent::Null => {
62                self.has_skipped_value = true;
63            }
64            JsonEvent::StartArray | JsonEvent::StartObject => {
65                self.has_skipped_value = true;
66                self.depth += 1;
67            }
68            JsonEvent::EndArray | JsonEvent::EndObject => {
69                if self.depth == 0 {
70                    return Err(SkipError::StackEmpty);
71                }
72                self.depth -= 1;
73            }
74            JsonEvent::ObjectKey(_) => {
75                if self.depth == 0 {
76                    return Err(SkipError::NestedObjectKey);
77                }
78            }
79            JsonEvent::Eof => {
80                return Err(SkipError::Eof);
81            }
82        }
83
84        Ok(self.skipping())
85    }
86}
87