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
use thiserror::Error;

use crate::parser::Error as ParseError;

/// Error with a location info.
pub trait LocatedError {
    /// get error happened location in source input.
    fn location(&self) -> (usize, usize);
}

/// Error for markup source compile pipeline.
///
/// Display this error in `{}` formatter will show a error message with detailed reason and location.
/// So usually you don't need check variants.
#[derive(Debug, PartialEq, Eq, Error)]
pub enum Error<'a, GE> {
    /// Parsing step failed, usually means there is invalid syntax in source string
    #[error("parse failed: {0}")]
    Parse(ParseError<'a>),

    /// Generating step failed, see document of generator type for detail.
    #[error("generator failed: {0}")]
    Gen(GE),
}

impl<'a, GE: LocatedError> LocatedError for Error<'a, GE> {
    fn location(&self) -> (usize, usize) {
        match self {
            Self::Parse(e) => e.location(),
            Self::Gen(e) => e.location(),
        }
    }
}

impl<'a, GE> From<ParseError<'a>> for Error<'a, GE> {
    fn from(e: ParseError<'a>) -> Self {
        Self::Parse(e)
    }
}