Skip to main content

glob_set/
error.rs

1use alloc::string::String;
2use core::fmt;
3
4/// An error that occurs when parsing a glob pattern.
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub struct Error {
7    /// The original glob pattern that caused this error.
8    glob: Option<String>,
9    /// The kind of error.
10    kind: ErrorKind,
11}
12
13impl Error {
14    pub(crate) fn new(kind: ErrorKind) -> Self {
15        Self { glob: None, kind }
16    }
17
18    pub(crate) fn with_glob(mut self, glob: &str) -> Self {
19        self.glob = Some(String::from(glob));
20        self
21    }
22
23    /// Return the glob pattern that caused this error, if available.
24    pub fn glob(&self) -> Option<&str> {
25        self.glob.as_deref()
26    }
27
28    /// Return the kind of this error.
29    pub fn kind(&self) -> &ErrorKind {
30        &self.kind
31    }
32}
33
34impl fmt::Display for Error {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        match &self.glob {
37            Some(glob) => write!(f, "error parsing glob '{}': {}", glob, self.kind),
38            None => write!(f, "error parsing glob: {}", self.kind),
39        }
40    }
41}
42
43impl core::error::Error for Error {}
44
45/// The kind of error that can occur when parsing a glob pattern.
46#[derive(Clone, Debug, Eq, PartialEq)]
47#[non_exhaustive]
48pub enum ErrorKind {
49    /// An unclosed character class, e.g., `[a-z`.
50    UnclosedClass,
51    /// An invalid character range, e.g., `[z-a]`.
52    InvalidRange(char, char),
53    /// An unopened alternation, e.g., `}`.
54    UnopenedAlternates,
55    /// An unclosed alternation, e.g., `{a,b`.
56    UnclosedAlternates,
57    /// A dangling escape, e.g., a pattern ending with `\`.
58    DanglingEscape,
59}
60
61impl fmt::Display for ErrorKind {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        match self {
64            Self::UnclosedClass => write!(f, "unclosed character class"),
65            Self::InvalidRange(lo, hi) => {
66                write!(f, "invalid character range '{lo}'-'{hi}'")
67            }
68            Self::UnopenedAlternates => write!(f, "unopened alternation group '}}' without '{{"),
69            Self::UnclosedAlternates => write!(f, "unclosed alternation group '{{' without '}}'"),
70            Self::DanglingEscape => write!(f, "dangling escape '\\' at end of pattern"),
71        }
72    }
73}