1use std::fmt::Display;
4
5#[derive(Debug, Clone, Default, PartialEq)]
7pub enum JsonElement {
8 #[default]
10 Null,
11 Boolean(bool),
13 Number(f64),
15 String(String),
17 Array(Vec<JsonElement>),
19 Object(Vec<(String, JsonElement)>),
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct ParseError {
31 pub msg: String,
33 pub line: usize,
35 pub column: usize,
37}
38
39#[derive(Debug, Clone, PartialEq)]
40pub struct JsonToken {
41 pub kind: TokenKind,
42 pub pos: TokenPosition,
43}
44
45#[derive(Debug, Clone, PartialEq)]
46pub enum TokenKind {
47 LeftBrace,
48 RightBrace,
49 LeftBracket,
50 RightBracket,
51 Comma,
52 Colon,
53 True,
54 False,
55 Null,
56 Number(f64),
57 String(String),
58 Eof,
59}
60
61#[derive(Debug, Clone, Copy, PartialEq)]
62pub struct TokenPosition {
63 pub line: usize,
64 pub column: usize,
65}
66
67impl ParseError {
68 pub fn new(msg: String, line: usize, column: usize) -> Self {
69 Self { msg, line, column }
70 }
71}
72
73impl Display for TokenKind {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 match self {
76 TokenKind::LeftBrace => f.write_str("'{'"),
77 TokenKind::RightBrace => f.write_str("'}'"),
78 TokenKind::LeftBracket => f.write_str("'['"),
79 TokenKind::RightBracket => f.write_str("']'"),
80 TokenKind::Comma => f.write_str("','"),
81 TokenKind::Colon => f.write_str("':'"),
82 TokenKind::True => f.write_str("boolean (true)"),
83 TokenKind::False => f.write_str("boolean (false)"),
84 TokenKind::Null => f.write_str("null"),
85 TokenKind::Number(n) => f.write_str(&format!("number ({n})")),
86 TokenKind::String(s) => f.write_str(&format!("string (\"{s}\")")),
87 TokenKind::Eof => f.write_str("end-of-file"),
88 }
89 }
90}
91
92impl JsonToken {
93 pub const fn dummy() -> Self {
94 let pos = TokenPosition { column: 0, line: 0 };
95 let kind = TokenKind::Null;
96 Self { pos, kind }
97 }
98
99 pub fn get_string(self) -> String {
100 match self.kind {
103 TokenKind::String(s) => s,
104 _ => panic!("Tried to extract a string from an invalid token"),
105 }
106 }
107}
108
109impl TokenKind {
110 pub fn same_kind(&self, other: &Self) -> bool {
111 core::mem::discriminant(self) == core::mem::discriminant(other)
112 }
113}
114
115impl Default for TokenPosition {
116 fn default() -> Self {
117 Self { line: 1, column: 0 }
118 }
119}