json_event_parser_blocks/
skipper.rs1use 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