1use std::error::Error;
10
11use displaydoc::Display;
12
13use crate::dom::Event;
14
15#[derive(Clone, Debug, Display)]
17#[non_exhaustive]
18pub enum ValidatorError {
19 TooManyEnd,
21 Unclosed,
23 Expected(&'static str, Event),
25}
26impl Error for ValidatorError {}
27
28#[derive(Debug, Clone, Copy)]
29enum State {
30 Block,
32 Node,
34}
35
36#[derive(Debug)]
38pub struct Validator {
39 nest: usize,
40 state: State,
41}
42
43impl Default for Validator {
44 fn default() -> Self { Self::new() }
45}
46
47impl Validator {
48 pub const fn new() -> Self {
50 Self {
51 nest: 0,
52 state: State::Block,
53 }
54 }
55 pub fn push(&mut self, event: &Event) -> Result<(), ValidatorError> {
59 self.state = match (self.state, event) {
60 (_, Event::End) => {
61 if let Some(nest) = self.nest.checked_sub(1) {
62 self.nest = nest;
63 State::Block
64 } else {
65 return Err(ValidatorError::TooManyEnd);
66 }
67 }
68 (State::Node, Event::Entry { .. }) => State::Node,
69 (State::Node, Event::Children) => State::Block,
70 (State::Block, Event::Node { .. }) => {
71 self.nest += 1;
72 State::Node
73 }
74 (State::Node, event) => {
75 return Err(ValidatorError::Expected(
76 "Entry, Children, or End",
77 event.clone(),
78 ));
79 }
80 (State::Block, event) => {
81 return Err(ValidatorError::Expected("Node or End", event.clone()));
82 }
83 };
84 Ok(())
85 }
86 pub fn done(self) -> Result<(), ValidatorError> {
90 if self.nest > 0 {
91 Err(ValidatorError::Unclosed)
92 } else {
93 Ok(())
94 }
95 }
96}