valkyrie_errors/parsing/
mod.rs1use std::{
2 char::ParseCharError,
3 fmt::{Display, Formatter},
4 num::{ParseFloatError, ParseIntError},
5 ops::Range,
6 str::ParseBoolError,
7};
8
9use ariadne::{Color, ReportKind};
10
11use crate::{FileID, FileSpan, ValkyrieError, ValkyrieErrorKind, ValkyrieReport};
12
13#[cfg(feature = "dashu")]
14mod for_dashu;
15#[cfg(feature = "json5")]
16mod for_json5;
17#[cfg(feature = "num")]
18mod for_num;
19#[cfg(feature = "peginator")]
20mod for_peginator;
21#[cfg(feature = "toml")]
22mod for_toml;
23
24#[cfg(feature = "pratt")]
25mod for_pratt;
26
27#[derive(Clone, Debug)]
28pub struct SyntaxError {
29 pub info: String,
30 pub span: FileSpan,
31}
32
33impl Display for SyntaxError {
34 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35 f.write_str(&self.info)
36 }
37}
38
39impl SyntaxError {
40 pub fn new(info: impl Into<String>) -> Self {
41 Self { span: FileSpan::default(), info: info.into() }
42 }
43 pub fn with_file(mut self, file: FileID) -> Self {
44 self.span.file = file;
45 self
46 }
47 pub fn with_range(mut self, range: &Range<usize>) -> Self {
48 self.span.head = range.start;
49 self.span.tail = range.end;
50 self
51 }
52 pub fn with_span(mut self, span: FileSpan) -> Self {
53 self.span = span;
54 self
55 }
56 pub fn as_report(&self, kind: ReportKind) -> ValkyrieReport {
57 let mut report = ValkyrieReport::build(kind, self.span.file, self.span.head);
58 report.set_message(self.to_string());
59 report.add_label(self.span.as_label(self.to_string()).with_color(Color::Red));
60 report.finish()
61 }
62}
63
64impl From<SyntaxError> for ValkyrieError {
65 fn from(value: SyntaxError) -> Self {
66 ValkyrieError { kind: ValkyrieErrorKind::Parsing(Box::new(value)), level: ReportKind::Error }
67 }
68}
69
70macro_rules! wrap_parse_error {
71 ($($type:ty),*) => {
72 $(
73 impl From<$type> for ValkyrieError {
74 fn from(value: $type) -> Self {
75 SyntaxError::new(value.to_string()).into()
76 }
77 }
78 )*
79 };
80}
81
82wrap_parse_error!(ParseIntError, ParseFloatError, ParseBoolError, ParseCharError, url::ParseError);
83
84#[cfg(feature = "num")]
85wrap_parse_error!(num::bigint::ParseBigIntError);
86
87#[cfg(feature = "dashu")]
88wrap_parse_error!(dashu::base::ParseError);