goglob_common/
error.rs

1use std::error::Error as StdError;
2use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
3use std::result::Result as StdResult;
4
5#[derive(Debug)]
6pub struct Error {
7    error_type: ErrorType,
8    pos: usize,
9}
10impl Error {
11    pub(crate) fn new(error_type: ErrorType, pos: usize) -> Self {
12        Self { error_type, pos }
13    }
14
15    pub(crate) fn empty_pattern() -> Self {
16        Self {
17            error_type: ErrorType::EmptyPattern,
18            pos: usize::MAX,
19        }
20    }
21
22    pub fn error_type(&self) -> &ErrorType {
23        &self.error_type
24    }
25
26    pub fn position(&self) -> usize {
27        self.pos
28    }
29}
30impl Display for Error {
31    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
32        self.error_type.fmt_with_pos(Some(self.pos), f)
33    }
34}
35impl StdError for Error {}
36
37#[derive(Copy, Clone)]
38pub enum ErrorType {
39    EmptyPattern,
40    IllegalEscape,
41    InvalidRangeValues(char, char),
42    UnclosedCharClass,
43    UnescapedChar(char),
44}
45impl ErrorType {
46    pub fn type_desc(&self) -> &'static str {
47        match self {
48            ErrorType::EmptyPattern => "empty pattern",
49            ErrorType::IllegalEscape => "illegal use of '\\': end of pattern",
50            ErrorType::InvalidRangeValues(_, _) => "invalid character range",
51            ErrorType::UnclosedCharClass => "character class opened with '[' isn't closed",
52            ErrorType::UnescapedChar(_) => "special character not escaped with '\\'",
53        }
54    }
55
56    pub fn full_desc(&self) -> String {
57        format!("{}", self)
58    }
59
60    pub fn fmt_with_pos(&self, pos: Option<usize>, f: &mut Formatter<'_>) -> FmtResult {
61        match (self, pos) {
62            (ErrorType::IllegalEscape, Some(pos)) => {
63                write!(f, "illegal use of '\\' at {pos}: end of pattern")
64            }
65            (ErrorType::InvalidRangeValues(start, end), Some(pos)) => {
66                write!(f, "invalid charater range at {pos}: {start}-{end}")
67            }
68            (ErrorType::InvalidRangeValues(start, end), None) => {
69                write!(f, "invalid charater range: {start}-{end}")
70            }
71            (ErrorType::UnclosedCharClass, Some(pos)) => {
72                write!(f, "character class opened with '[' at {pos} isn't closed")
73            }
74            (ErrorType::UnescapedChar(unescaped), Some(pos)) => {
75                write!(
76                    f,
77                    "special character {unescaped} at {pos} not escaped with '\\'"
78                )
79            }
80            (ErrorType::UnescapedChar(unescaped), None) => {
81                write!(f, "special character {unescaped} not escaped with '\\'")
82            }
83            (_, _) => f.write_str(self.type_desc()),
84        }
85    }
86}
87impl Debug for ErrorType {
88    #[inline]
89    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
90        self.fmt_with_pos(None, f)
91    }
92}
93impl Display for ErrorType {
94    #[inline]
95    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
96        self.fmt_with_pos(None, f)
97    }
98}
99
100pub type Result<T> = StdResult<T, Error>;