1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! Events generated by the SAX parser
//!
//!
use crate::coords::Span;
use crate::errors::ParserError;
use crate::pointer::JsonPointer;
use std::borrow::Cow;
use std::fmt::Display;

/// Enumeration of the various different matches that can be produced during a parse
pub enum Match<'a> {
    /// Start of the input Emitted prior to anything else
    StartOfInput,
    /// End of the input Emitted after everything else
    EndOfInput,
    /// Emitted when the start of a new object is matched
    StartObject,
    /// Emitted when a new key within an object is matched
    ObjectKey(Cow<'a, str>),
    /// Emitted after an object has been fully parsed
    EndObject,
    /// Emitted when the start of an array is matched
    StartArray,
    /// Emitted when the end of an array is matched
    EndArray,
    /// Emitted when a string is matched
    String(Cow<'a, str>),
    /// Emitted when an integer is matched
    Integer(i64),
    /// Emitted when a float is matched
    Float(f64),
    /// Emitted when a boolean is matched
    Boolean(bool),
    /// Emitted when a null is matched
    Null,
}

impl<'a> Display for Match<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Match::StartOfInput => write!(f, "StartOfInput"),
            Match::EndOfInput => write!(f, "EndOfInput"),
            Match::StartObject => write!(f, "StartObject"),
            Match::ObjectKey(_) => write!(f, "ObjectKey"),
            Match::EndObject => write!(f, "EndObject"),
            Match::StartArray => write!(f, "StartArray"),
            Match::EndArray => write!(f, "EndArray"),
            Match::String(value) => write!(f, "String({})", value),
            Match::Integer(value) => write!(f, "Integer({})", value),
            Match::Float(value) => write!(f, "Float({})", value),
            Match::Boolean(b) => write!(f, "Boolean({})", b),
            Match::Null => write!(f, "Null"),
        }
    }
}

/// An event produced by the parser during a parse
pub struct Event<'a> {
    /// The [Match] associated with the event
    pub matched: Match<'a>,

    /// The [Span] associated with the current [Match]
    pub span: Span,

    /// Optional [JsonPointer] information relating to the event
    pub pointer: Option<&'a JsonPointer<'a>>,
}

impl<'a> Event<'a> {
    /// Checks whether an event has a path or not
    fn has_pointer(&self) -> bool {
        self.pointer.is_some()
    }
}

impl<'a> Display for Event<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if self.pointer.is_some() {
            write!(
                f,
                "Event[{}, {}, {}]",
                self.matched,
                self.span,
                self.pointer.unwrap()
            )
        } else {
            write!(f, "Event[{}, {}]", self.matched, self.span)
        }
    }
}