summaryrefslogtreecommitdiff
path: root/chewed/src/error.rs
blob: afe65c0a4ea77a722b8f3643f6f17f5b542fd633 (plain)
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
use std::{error::Error, fmt};

use super::position::LineCol;

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum TakeError {
    BadBranch(LineCol, char, &'static [char]),
    BadString(LineCol, String, &'static str),
    EndOfStream(LineCol),
}

impl fmt::Display for TakeError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::BadBranch(pos, got, expected) => {
                write!(f, "{}: Unexpected character {:?}. ", pos, got)?;

                if expected.is_empty() {
                    write!(f, "Expected end of input.")
                } else if expected.len() == 1 {
                    write!(f, "Expected character {:?}.", expected[0])
                } else {
                    let mut iter = expected.iter();
                    write!(f, "Expected one of {:?}", iter.next().unwrap())?;

                    for c in iter {
                        write!(f, ", {:?}", c)?;
                    }

                    Ok(())
                }
            }
            Self::BadString(pos, got, expected) => write!(
                f,
                "{}: Unexpected string {:?}. Expected {:?}",
                pos, got, expected
            ),
            Self::EndOfStream(pos) => write!(f, "{}: Unexpected end of input", pos),
        }
    }
}

impl Error for TakeError {}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum ParseError {
    TakeError(TakeError),
    InputContinues(LineCol),
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::TakeError(e) => e.fmt(f),
            Self::InputContinues(pos) => write!(f, "{}: Expected end of input", pos),
        }
    }
}

impl Error for ParseError {}

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