1use std::{collections::HashMap, fmt::Display, hash::Hash};
2
3use jsode_macro::reflection;
4
5use crate::{common::Arrice, error::JsonError, parser::JsonParser};
6
7#[derive(PartialEq, PartialOrd, Debug)]
8pub enum JsonType {
9 Ident,
10 Str(Vec<StrType>),
12 Num(NumType),
14 Bool(bool),
16 Null,
18}
19
20impl JsonType {
21 pub const fn get_type_name(&self) -> &str {
22 match self {
23 Self::Bool(_) => "boolean",
24 Self::Ident => "ident",
25 Self::Num(num) => num.get_type_name(),
26 Self::Str(_) => "string",
27 Self::Null => "null",
28 }
29 }
30}
31
32#[derive(PartialEq, PartialOrd, Debug, Clone)]
33pub enum StrType {
34 Str(Span),
35 Ascii(Span),
37 Unicode(Span),
39 Escape(Span),
41 Special(Span),
52}
53
54impl StrType {
55 pub const fn get_type_name(&self) -> &str {
56 match self {
57 Self::Ascii(_) => "ascii",
58 Self::Escape(_) => "escape",
59 Self::Special(_) => "special",
60 Self::Unicode(_) => "unicode",
61 Self::Str(_) => "normal str",
62 }
63 }
64}
65
66#[derive(PartialEq, PartialOrd, Debug, Clone)]
67pub enum NumType {
68 Integer(Integer),
74 Decimal(Decimal),
81 Hex(Heximal),
84 Infinity(Span),
86 NaN(Span),
88}
89
90impl NumType {
91 pub const fn get_type_name(&self) -> &str {
92 match self {
93 Self::Integer(_) => "integer",
94 Self::Decimal(_) => "decimal",
95 Self::Hex(_) => "hexadecimal",
96 Self::Infinity(_) => "infinity",
97 Self::NaN(_) => "NaN",
98 }
99 }
100}
101
102#[derive(PartialEq, PartialOrd, Debug, Clone)]
103pub enum Integer {
104 Positive(Span, Option<Span>),
108 Negative(Span, Option<Span>),
109}
110
111#[derive(PartialEq, PartialOrd, Debug, Clone)]
112pub enum Heximal {
113 Positive(Span, Span),
117 Negative(Span, Span),
118}
119
120#[derive(PartialEq, PartialOrd, Debug, Clone)]
121pub enum Decimal {
122 Positive(Option<Span>, Option<Span>, Option<Span>),
127 Negative(Option<Span>, Option<Span>, Option<Span>),
128}
129
130impl From<Decimal> for NumType {
131 fn from(value: Decimal) -> Self {
132 NumType::Decimal(value)
133 }
134}
135
136impl From<Integer> for NumType {
137 fn from(value: Integer) -> Self {
138 NumType::Integer(value)
139 }
140}
141
142impl From<Heximal> for NumType {
143 fn from(value: Heximal) -> Self {
144 NumType::Hex(value)
145 }
146}
147
148#[derive(PartialEq, PartialOrd, Debug, Clone)]
149pub enum Sign {
150 Plus,
151 Minus,
152 None,
153}
154
155impl Sign {
156 pub const fn detect(sign: u8) -> Self {
157 match sign {
158 43 => Self::Plus,
159 45 => Self::Minus,
160 _ => Self::None,
161 }
162 }
163
164 #[rustfmt::skip]
165 pub const fn compute_start_pos(&self, start: usize) -> usize {
166 match self {
169 Self::Plus => start - 1,
171 Self::Minus => start - 1,
173 _ => start,
175 }
176 }
177
178 pub const fn to_hexadecimal(&self, prefix: Span, suffix: Span) -> NumType {
179 match self {
180 Self::Plus => NumType::Hex(Heximal::Positive(prefix.expand_left(1), suffix)),
181 Self::Minus => NumType::Hex(Heximal::Negative(prefix.expand_left(1), suffix)),
182 _ => NumType::Hex(Heximal::Positive(prefix, suffix)),
183 }
184 }
185
186 pub const fn to_integer(&self, start: usize, end: usize, expo_span: Option<Span>) -> NumType {
187 match self {
188 Self::Plus => NumType::Integer(Integer::Positive(Span::new(start - 1, end), expo_span)),
189 Self::Minus => NumType::Integer(Integer::Negative(Span::new(start - 1, end), expo_span)),
190 _ => NumType::Integer(Integer::Positive(Span::new(start, end), expo_span)),
191 }
192 }
193
194 pub const fn to_decimal(&self, int_span: Option<Span>, frac_span: Option<Span>, expo_span: Option<Span>) -> NumType {
195 let new_int_span = if let Some(integer_span) = int_span { Some(integer_span.expand_left(1)) } else { None };
196 match self {
197 Self::Plus => NumType::Decimal(Decimal::Positive(new_int_span, frac_span, expo_span)),
198 Self::Minus => NumType::Decimal(Decimal::Negative(new_int_span, frac_span, expo_span)),
199 _ => NumType::Decimal(Decimal::Positive(new_int_span, frac_span, expo_span)),
200 }
201 }
202}
203
204impl StrType {
205 pub(crate) fn parse_str<'a>(&'a self, parser: &'a JsonParser<'a>) -> Result<&'a str> {
206 match self {
207 Self::Str(span) => Ok(parser.take_slice(Span::new(span.start, span.end))?),
208 Self::Ascii(span) => Ok(parser.take_slice(Span::new(span.start + 2, span.end))?),
209 Self::Unicode(span) => Ok(parser.take_slice(Span::new(span.start + 2, span.end))?),
210 Self::Escape(span) => Ok(parser.take_slice(Span::new(span.start + 1, span.end))?),
211 Self::Special(span) => {
212 let raw = parser.take_raw(span.clone());
213 let item = map_special_char(raw[0]);
214 Ok(item)
215 },
216 }
217 }
218}
219
220const fn map_special_char<'a>(c: u8) -> &'a str {
221 match c {
222 b'\'' => "\'",
223 b'\"' => "\"",
224 b'\\' => "\\",
225 b'b' => "\u{08}",
226 b'f' => "\u{0C}",
227 b'n' => "\u{0A}",
228 b'r' => "\u{0D}",
229 b't' => "\u{09}",
230 b'v' => "\u{0B}",
231 b'0' => "\u{00}",
232 _ => "\u{00}",
233 }
234}
235
236#[derive(PartialEq, PartialOrd, Debug)]
237pub enum Punct {
238 DoubleQuote,
239 SingleQuote,
240 Comma ,
241 Colon ,
242 OpenSquare ,
243 CloseSquare,
244 OpenCurly ,
245 CloseCurly ,
246 WhiteSpace ,
247 Plus ,
248 Minus ,
249}
250
251#[derive(Default, PartialEq, Eq, PartialOrd, Hash, Clone, Debug)]
252pub struct Span {
253 pub start: usize,
254 pub end: usize,
255 pub col: usize,
256 pub row: usize,
257}
258
259impl Span {
260 #[inline(always)]
261 pub const fn new(start: usize, end: usize) -> Self {
262 Self { start, end, col: 0, row: 0 }
263 }
264
265 #[inline(always)]
266 pub const fn with_counter(start: usize, counter: usize) -> Self {
267 Self { start, end: start + counter, col: 0, row: 0 }
268 }
269
270 #[inline(always)]
271 pub const fn gap(&self) -> usize {
272 self.end - self.start
273 }
274
275 #[inline]
276 pub const fn extend(&self, other: Span) -> Self {
277 Span::new(self.start, other.end)
278 }
279
280 #[inline(always)]
281 pub const fn collapse(mut self, size: usize) -> Self {
282 self.start += size;
283 self.end -= size;
284 self
285 }
286
287 #[inline(always)]
288 pub const fn shrink_left(mut self, size: usize) -> Self {
289 self.start += size;
290 self
291 }
292
293 #[inline(always)]
294 pub const fn shrink_right(mut self, size: usize) -> Self {
295 self.end -= size;
296 self
297 }
298
299 #[inline(always)]
300 pub const fn expand_left(mut self, size: usize) -> Self {
301 self.start -= size;
302 self
303 }
304
305 #[inline(always)]
306 pub const fn expand_right(mut self, size: usize) -> Self {
307 self.end += size;
308 self
309 }
310}
311
312#[derive(PartialEq, PartialOrd, Debug)]
313pub enum JsonToken {
314 Punct(Punct, Span),
315 Data(JsonType, Span),
316 Error(String, Span),
317 Comment(Span),
318}
319
320impl JsonToken {
321 #[inline(always)]
322 pub const fn ident(start: usize, end: usize) -> Self { Self::Data(JsonType::Ident, Span::new(start, end)) }
323 #[inline(always)]
324 pub const fn str(str_tokens: Vec<StrType>, start: usize, end: usize) -> Self { Self::Data(JsonType::Str(str_tokens), Span::new(start, end)) }
325 #[inline(always)]
326 pub const fn number(ty: NumType, start: usize, end: usize) -> Self { Self::Data(JsonType::Num(ty), Span::new(start, end)) }
327 #[inline(always)]
328 pub const fn boolean(value: bool, start: usize) -> Self { Self::Data(JsonType::Bool(value), Span::new(start, start + if value { 4 } else { 5 })) }
329 #[inline(always)]
330 pub const fn null(at: usize) -> Self { Self::Data(JsonType::Null, Span::new(at, at + 1)) }
331 #[inline(always)]
332 pub const fn open_curly(at: usize) -> Self { Self::Punct(Punct::OpenCurly, Span::new(at, at + 1)) }
333 #[inline(always)]
334 pub const fn close_curly(at: usize) -> Self { Self::Punct(Punct::CloseCurly, Span::new(at, at + 1)) }
335 #[inline(always)]
336 pub const fn open_square(at: usize) -> Self { Self::Punct(Punct::OpenSquare, Span::new(at, at + 1)) }
337 #[inline(always)]
338 pub const fn close_square(at: usize) -> Self { Self::Punct(Punct::CloseSquare, Span::new(at, at + 1)) }
339 #[inline(always)]
340 pub const fn single_quote(at: usize) -> Self { Self::Punct(Punct::SingleQuote, Span::new(at, at + 1)) }
341 #[inline(always)]
342 pub const fn double_quote(at: usize) -> Self { Self::Punct(Punct::DoubleQuote, Span::new(at, at + 1)) }
343 #[inline(always)]
344 pub const fn colon(at: usize) -> Self { Self::Punct(Punct::Colon, Span::new(at, at + 1)) }
345 #[inline(always)]
346 pub const fn comma(at: usize) -> Self { Self::Punct(Punct::Comma, Span::new(at, at + 1)) }
347 #[inline(always)]
348 pub const fn whitespace(at: usize, end: usize) -> Self { Self::Punct(Punct::WhiteSpace, Span::new(at, end)) }
349 #[inline(always)]
350 pub const fn plus(at: usize, end: usize) -> Self { Self::Punct(Punct::Plus, Span::new(at, end)) }
351 #[inline(always)]
352 pub const fn minus(at: usize, end: usize) -> Self { Self::Punct(Punct::Minus, Span::new(at, end)) }
353 #[inline(always)]
354 pub const fn comment(at: usize, end: usize) -> Self { Self::Comment(Span::new(at, end)) }
355
356 #[inline(always)]
357 pub fn error(msg: impl Into<String>, start: usize, end: usize) -> Self { Self::Error(msg.into(), Span::new(start, end)) }
358}
359
360impl From<JsonError> for JsonToken {
361 fn from(value: JsonError) -> Self {
362 JsonToken::Error(value.to_string(), value.span)
363 }
364}
365
366impl JsonToken {
367 pub fn parse_keyword(src: &str, start: usize, end: usize) -> JsonToken {
368 match &src[start..start + end] {
369 "true" => JsonToken::boolean(true, start),
370 "false" => JsonToken::boolean(false, start),
371 _ => JsonToken::ident(start, end),
372 }
373 }
374
375 pub const fn get_span(&self) -> Span {
376 match self {
377 Self::Data(_, span) => Span::new(span.start, span.end),
378 Self::Punct(_, span) => Span::new(span.start, span.end),
379 Self::Error(_, span) => Span::new(span.start, span.end),
380 Self::Comment(span) => Span::new(span.start, span.end),
381 }
382 }
383}
384
385#[derive(PartialEq, Debug)]
386pub struct JsonBlock {
387 pub(crate) level: usize,
388 pub(crate) value: JsonValue,
389}
390
391impl Default for JsonBlock {
392 fn default() -> Self {
393 Self { level: 0, value: JsonValue::Array(Vec::with_capacity(10), Span::default()) }
394 }
395}
396
397impl JsonBlock {
398 pub fn new(level: usize, value: JsonValue) -> Self {
399 Self { level, value }
400 }
401
402 #[inline]
403 pub(crate) fn parse_type<T: std::str::FromStr>(&self, parser: &JsonParser<'_>) -> Result<T>
404 where T::Err: Display {
405 let span = self.value.get_span();
406 let slice = parser.take_slice(span.clone())?;
407 slice.parse::<T>().map_err(|err| JsonError::custom(format!("{err}"), span))
408 }
409
410 #[inline]
411 pub(crate) fn parse_type_span<T: std::str::FromStr>(&self, parser: &JsonParser<'_>, span: Span) -> Result<T>
412 where T::Err: Display {
413 let slice = parser.take_slice(span.clone())?;
414 slice.parse::<T>().map_err(|err| JsonError::custom(format!("{err}"), span))
415 }
416
417 #[inline]
418 pub fn to_slice<'a>(&'a self, parser: &'a JsonParser<'a>) -> Result<&str> {
419 let span = self.value.get_span();
420 parser.take_slice(span)
421 }
422
423 pub const fn to_bytes<'a>(&'a self, parser: &'a JsonParser<'a>) -> &[u8] {
424 let span = self.value.get_span();
425 parser.take_raw(span)
426 }
427}
428
429#[derive(PartialEq, Debug)]
430pub struct JsonOutput<'out> {
431 pub(crate) parser: &'out JsonParser<'out>,
432 pub(crate) ast: Arrice<'out, JsonBlock>,
433}
434
435impl <'out> JsonOutput<'out> {
436 pub fn new(parser: &'out JsonParser<'out>, ast: impl Into<Arrice<'out, JsonBlock>>) -> Self {
437 Self { parser, ast: ast.into(), }
438 }
439
440 #[inline]
441 #[reflection]
442 pub(crate) fn parse_type<T: std::str::FromStr>(&self) -> Result<T>
443 where T::Err: Display {
444 self.ast.as_slice().first()
445 .map(|it| it.parse_type(self.parser))
446 .ok_or(JsonError::custom(format!("[{__fn_ident}] Soon EOF"), Span::default()))?
447 }
448
449 #[inline]
450 #[reflection]
451 pub(crate) fn parse_type_span<T: std::str::FromStr>(&self, span: Span) -> Result<T>
452 where T::Err: Display {
453 self.ast.as_slice().first()
454 .map(|it| it.parse_type_span(self.parser, span))
455 .ok_or(JsonError::custom(format!("[{__fn_ident}] Soon EOF"), Span::default()))?
456 }
457
458 #[inline]
459 #[reflection]
460 pub fn to_slice(&self) -> Result<&str> {
461 self.ast.as_slice().first()
462 .map(|it| it.to_slice(self.parser))
463 .ok_or(JsonError::custom(format!("[{__fn_ident}] Soon EOF"), Span::default()))?
464 }
465
466 #[inline]
467 pub fn to_slice_span(&self, span: Span) -> Result<&str> {
468 self.parser.take_slice(span)
469 }
470
471 pub fn to_bytes(&self) -> Result<&[u8]> {
472 self.ast.as_slice().first()
473 .map(|it| Ok(it.to_bytes(self.parser)))
474 .ok_or(JsonError::custom("msg", Span::default()))?
475 }
476}
477
478#[derive(PartialEq, Debug)]
479pub enum JsonValue {
480 Object(HashMap<usize,usize>, Span),
481 Array(Vec<usize>, Span),
482 Prop(JsonType, Span, Span),
487 Value(JsonType, Span),
488}
489
490impl JsonValue {
491 #[inline]
492 pub const fn get_span(&self) -> Span {
493 match self {
494 Self::Object(_, span) => Span::new(span.start, span.end),
495 Self::Array(_, span) => Span::new(span.start, span.end),
496 Self::Prop(_, span, _) => Span::new(span.start, span.end),
497 Self::Value(_, span) => Span::new(span.start, span.end),
498 }
499 }
500
501 #[inline(always)]
502 pub const fn get_type_name(&self) -> &str {
503 match self {
504 Self::Object(_,_) => "object",
505 Self::Array(_,_) => "array",
506 Self::Prop(data_ty,_,_) => data_ty.get_type_name(),
507 Self::Value(data_ty, _) => data_ty.get_type_name()
508 }
509 }
510}
511
512pub type Result<T> = core::result::Result<T, JsonError>;