use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ErrorKind {
Syntax(String),
BadEscape(String),
BadCharClass(String),
BadRepeat(String),
BadGroupRef(String),
DuplicateGroup(String),
BadFlag(String),
BadProperty(String),
TooLarge(String),
Timeout,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Error {
pub kind: ErrorKind,
pub position: Option<usize>,
}
impl Error {
pub fn syntax_at(msg: impl Into<String>, pos: usize) -> Self {
Error {
kind: ErrorKind::Syntax(msg.into()),
position: Some(pos),
}
}
pub fn syntax(msg: impl Into<String>) -> Self {
Error {
kind: ErrorKind::Syntax(msg.into()),
position: None,
}
}
pub fn at(kind: ErrorKind, pos: usize) -> Self {
Error {
kind,
position: Some(pos),
}
}
pub fn new(kind: ErrorKind) -> Self {
Error {
kind,
position: None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let msg = match &self.kind {
ErrorKind::Syntax(s)
| ErrorKind::BadEscape(s)
| ErrorKind::BadCharClass(s)
| ErrorKind::BadRepeat(s)
| ErrorKind::BadGroupRef(s)
| ErrorKind::DuplicateGroup(s)
| ErrorKind::BadFlag(s)
| ErrorKind::BadProperty(s)
| ErrorKind::TooLarge(s) => s,
ErrorKind::Timeout => "regex timed out",
};
match self.position {
Some(p) => write!(f, "eregex error at position {p}: {msg}"),
None => write!(f, "eregex error: {msg}"),
}
}
}
impl std::error::Error for Error {}