nyar_error/undefined/
mod.rs1use crate::{NyarError, NyarErrorKind};
2use diagnostic::{Color, Diagnostic, Label, ReportKind, SourceID, SourceSpan};
3use std::{
4 error::Error,
5 fmt::{Debug, Display, Formatter},
6 ops::Range,
7};
8
9#[derive(Clone, Debug, Eq, PartialEq)]
10pub struct MissingError {
11 pub(crate) kind: MissingErrorKind,
12 pub(crate) span: SourceSpan,
13}
14
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub(crate) enum MissingErrorKind {
17 EmptyPath,
19 Undefined(Box<str>),
21}
22
23impl Error for MissingError {}
24
25impl Display for MissingError {
26 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27 Display::fmt(&self.kind, f)
28 }
29}
30
31impl Display for MissingErrorKind {
32 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
33 match self {
34 Self::EmptyPath => write!(f, "Empty symbol"),
35 Self::Undefined(v) => write!(f, "Undefined symbol `{}`", v),
36 }
37 }
38}
39
40impl From<MissingError> for NyarError {
41 fn from(value: MissingError) -> Self {
42 value.as_error(ReportKind::Error)
43 }
44}
45
46impl MissingError {
47 pub fn empty() -> Self {
48 Self { kind: MissingErrorKind::EmptyPath, span: SourceSpan::default() }
49 }
50 pub fn undefined(symbol: &str) -> Self {
51 Self { kind: MissingErrorKind::Undefined(Box::from(symbol)), span: SourceSpan::default() }
52 }
53 pub fn with_span(self, span: SourceSpan) -> Self {
54 Self { span, ..self }
55 }
56 pub fn with_range(self, range: Range<u32>) -> Self {
57 Self { span: self.span.with_range(range), ..self }
58 }
59 pub fn with_file(self, file: SourceID) -> Self {
60 Self { span: self.span.with_file(file), ..self }
61 }
62 pub fn as_error(self, kind: ReportKind) -> NyarError {
63 NyarErrorKind::Missing(self).as_error(kind)
64 }
65 pub fn as_report(&self, kind: ReportKind) -> Diagnostic {
66 let mut report = Diagnostic::new(kind).with_location(self.span.get_file(), Some(self.span.get_start()));
67 report.set_message(self.to_string());
68 match self.kind {
69 MissingErrorKind::EmptyPath => {
70 report.add_label(Label::new(self.span).with_message("Symbol path cannot be empty").with_color(Color::Red))
71 }
72 MissingErrorKind::Undefined(_) => report.add_label(
73 Label::new(self.span).with_message("You need to declare this symbol by `let` first").with_color(Color::Red),
74 ),
75 }
76 report.finish()
77 }
78}