1pub mod parser;
11pub mod token;
12
13#[derive(thiserror::Error, Debug)]
15pub enum Error {
16 #[error("Error: {0}")]
18 Error(String),
19
20 #[error("Invalid String: {0}")]
22 InvalidString(String),
23
24 #[error("Tokenize: {0}")]
26 Tokenize(String),
27
28 #[error("Unexpected token")]
29 UnexpectedToken,
30
31 #[error("Unexpected length")]
32 UnexpectedLength,
33
34 #[error("Unexpected value")]
35 UnexpectedValue,
36
37 #[error("Unsupported")]
38 Unsupported,
39
40 #[error("Parse: {0}")]
42 Parser(String),
43
44 #[error("serde_json")]
45 Serde(#[from] serde_json::Error),
46
47 #[error("IO")]
48 Io(#[from] std::io::Error),
49
50 #[error("Utf8")]
51 Utf8(#[from] std::str::Utf8Error),
52}
53type Result<T> = std::result::Result<T, Error>;
54
55macro_rules! errloc {
56 () => {{
57 let line = line!();
58 let file = file!();
59 format!("{file}:{line}")
60 }};
61}
62
63pub(crate) use errloc;
64
65macro_rules! parsererror {
66 ($msg:expr) => {{
67 let errloc = crate::errloc!();
68 let err = format!("{errloc}: error: {}", $msg);
69 log::error!("{err}");
70 Err(crate::Error::Parser(err))
71 }};
72}
73pub(crate) use parsererror;
74
75macro_rules! generror {
76 ($msg:expr, $log:ident) => {{
77 let errloc = crate::errloc!();
78 let err = format!("{errloc}: error: {}", $msg);
79 log::$log!("{err}");
80 Err(crate::Error::Error(err))
81 }};
82 ($msg:expr) => {
83 generror!($msg, error)
84 };
85}
86pub(crate) use generror;
87
88macro_rules! verify {
89 ($expr:expr, $error:ident) => {
90 if (!($expr)) {
91 let errloc = crate::errloc!();
92 log::error!("{errloc}: expression failed: {}", stringify!($expr));
93 return Err(crate::Error::$error);
94 }
95 };
96}
97pub(crate) use verify;
98
99macro_rules! consume {
100 ($tokens:expr, $check:expr) => {{
101 if $tokens.is_empty() {
102 let errloc = crate::errloc!();
103 let msg = format!("{errloc}: expected {:?}, but tokens is empty", $check);
104 log::error!("{msg}");
105 return Err(crate::Error::Parser(msg));
106 }
107 let t = $tokens.remove(0);
108 if t != $check {
109 let errloc = crate::errloc!();
110 let msg = format!("{errloc}: expected {:?}, but got token {:?}", $check, t);
111 log::error!("{msg}");
112 return Err(crate::Error::Parser(msg));
113 }
114 t
115 }};
116 ($tokens:expr) => {{
117 if $tokens.is_empty() {
118 let errloc = crate::errloc!();
119 let msg = format!("{errloc}: expected new value but tokens is empty");
120 log::error!("{msg}");
121 return Err(crate::Error::Parser(msg));
122 }
123 $tokens.remove(0)
124 }};
125}
126pub(crate) use consume;
127
128macro_rules! check_empty {
129 ($tokens:expr) => {
130 if !$tokens.is_empty() {
131 let errloc = crate::errloc!();
132 let msg = format!("{errloc}: expected tokens to be empty, left: {:?}", $tokens);
133 log::error!("{msg}");
134 return Err(crate::Error::Parser(msg));
135 }
136 };
137}
138pub(crate) use check_empty;
139
140macro_rules! gen_get_ident {
141 ($name:ident) => {
142 pub fn identifier(&self) -> &Identifier {
144 &self.$name
145 }
146 };
147}
148pub(crate) use gen_get_ident;
149
150macro_rules! gen_get {
151 ($funcname:ident, $field:ident, $val:ty) => {
152 pub fn $funcname(&self) -> &$val {
153 &self.$field
154 }
155 };
156 ($field:ident, $val:ty) => {
157 gen_get! { $field, $field, $val }
158 };
159}
160
161pub(crate) use gen_get;
162
163macro_rules! gen_get_mut {
164 ($funcname:ident, $field:ident, $val:ty) => {
165 pub fn $funcname(&mut self) -> &mut $val {
166 &mut self.$field
167 }
168 };
169 ($field:ident, $val:ty) => {
170 gen_get_mut! { $field, $field, $val }
171 };
172}
173
174pub(crate) use gen_get_mut;
175
176macro_rules! gen_get_iter {
177 ($funcname:ident, $field:ident, $val:ty) => {
178 pub fn $funcname(&self) -> std::slice::Iter<'_, $val> {
179 self.$field.iter()
180 }
181 };
182 ($field:ident, $val:ty) => {
183 gen_get_iter! { $field, $field, $val }
184 };
185}
186pub(crate) use gen_get_iter;
187
188macro_rules! gen_find_ident {
189 ($field:ident) => {
190 pub fn find_ident<'a>(entries: &'a [Self], ident: &Identifier) -> Option<&'a Self> {
192 for val in entries.iter() {
193 if val.$field == *ident {
194 return Some(val);
195 }
196 }
197 None
198 }
199 };
200 ($field:ident, $val:ty) => {
201 gen_get_iter! { $field, $field, $val }
202 };
203}
204pub(crate) use gen_find_ident;
205
206macro_rules! gen_get_ident_matches {
207 ($name:ident) => {
208 pub fn ident_matches(&self, name: &str) -> bool {
210 self.$name.name == name
211 }
212 };
213}
214pub(crate) use gen_get_ident_matches;
215
216macro_rules! gen_find_by_ident {
217 ($name:ident, $field:ident, $val:ty) => {
218 pub fn $name(&self, ident: &Identifier) -> Option<&$val> {
219 self.$field.iter().find(|&s| s.identifier() == ident)
220 }
221 };
222}
223pub(crate) use gen_find_by_ident;
224
225macro_rules! gen_find_by_name {
226 ($name:ident, $field:ident, $val:ty) => {
227 pub fn $name<I: Into<Identifier>>(&self, name: I) -> Option<&$val> {
228 let ident: Identifier = name.into();
229 self.$field.iter().find(|&s| s.identifier() == &ident)
230 }
231 };
232}
233pub(crate) use gen_find_by_name;
234
235#[cfg(test)]
236#[ctor::ctor]
237fn global_test_setup() {
238 env_logger::init();
239}