use super::lexer::LexerError;
use thiserror::Error;
pub type FilterResult<T> = Result<T, FilterError>;
#[derive(Debug, Clone, Error, PartialEq, Eq)]
pub enum FilterError {
#[error("filter expression is empty")]
EmptyExpression,
#[error("unexpected token '{token}' at position {position}")]
UnexpectedToken {
token: String,
position: usize,
},
#[error("unexpected end of expression after position {position}")]
UnexpectedEndOfInput {
position: usize,
},
#[error("invalid priority '{value}' at position {position} (expected 1-4)")]
InvalidPriority {
value: String,
position: usize,
},
#[error("unclosed parenthesis at position {position}")]
UnclosedParenthesis {
position: usize,
},
#[error("unknown filter keyword '{keyword}' at position {position}")]
UnknownKeyword {
keyword: String,
position: usize,
},
#[error("unknown character(s) in filter: {}", format_lexer_errors(.errors))]
UnknownCharacters {
errors: Vec<LexerError>,
},
}
fn format_lexer_errors(errors: &[LexerError]) -> String {
if errors.len() == 1 {
format!(
"'{}' at position {}",
errors[0].character, errors[0].position
)
} else {
errors
.iter()
.map(|e| format!("'{}' at {}", e.character, e.position))
.collect::<Vec<_>>()
.join(", ")
}
}
impl FilterError {
pub fn unexpected_token(token: impl Into<String>, position: usize) -> Self {
FilterError::UnexpectedToken {
token: token.into(),
position,
}
}
pub fn unexpected_end_of_input(position: usize) -> Self {
FilterError::UnexpectedEndOfInput { position }
}
pub fn invalid_priority(value: impl Into<String>, position: usize) -> Self {
FilterError::InvalidPriority {
value: value.into(),
position,
}
}
pub fn unclosed_parenthesis(position: usize) -> Self {
FilterError::UnclosedParenthesis { position }
}
pub fn unknown_keyword(keyword: impl Into<String>, position: usize) -> Self {
FilterError::UnknownKeyword {
keyword: keyword.into(),
position,
}
}
}