valkyrie_errors/parsing/
mod.rs

1use 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);