1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::error::Error;

use pest::error::Error as PestError;

use crate::parser::Rule;

#[derive(Debug)]
pub enum CalcError {
    ParseError(PestError<Rule>),
    UnitError(String),
    MathError,
    Other(String),
}

impl std::fmt::Display for CalcError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            CalcError::ParseError(e) => {
                let location = &e.line_col;
                match location {
                    pest::error::LineColLocation::Pos((line, col)) => {
                        writeln!(f, "Parsing Error near line {} column {}", line, col)
                    }
                    pest::error::LineColLocation::Span((l1, c1), (l2, c2)) => {
                        writeln!(
                            f,
                            "Parsing Error near span from line {}, column {} to line {} column {}",
                            l1, c1, l2, c2,
                        )
                    }
                }
            }
            CalcError::UnitError(s) => {
                write!(f, "{}", s)
            }
            CalcError::MathError => {
                write!(f, "Bad Math")
            }
            CalcError::Other(s) => {
                write!(f, "{}", s)
            }
        }
    }
}

impl Error for CalcError {
    fn description(&self) -> &str {
        use CalcError::*;
        match self {
            ParseError(_) => "Parse Error",
            UnitError(_) => "Unit Error",
            MathError => "Math Error",
            Other(_) => "Error",
        }
    }
}

impl From<PestError<Rule>> for CalcError {
    fn from(e: PestError<Rule>) -> Self {
        CalcError::ParseError(e)
    }
}

impl From<&str> for CalcError {
    fn from(s: &str) -> Self {
        CalcError::Other(s.to_owned())
    }
}

impl CalcError {
    pub fn add_line(self, line: usize) -> Self {
        CalcError::Other(format!("Line {}: {}", line, self))
    }
}