diff options
author | Daniel <kingdread@gmx.de> | 2020-04-26 11:45:37 +0200 |
---|---|---|
committer | Daniel <kingdread@gmx.de> | 2020-04-26 11:45:37 +0200 |
commit | 13053073e3336b8e6ffefd6a056d159239550be7 (patch) | |
tree | 63544e8764b55563a48d3f9fd530b0381f42a277 /src/fexpr/mod.rs | |
parent | 3c429432382dfad6d4ac97349c96e4a4eb292089 (diff) | |
parent | 9bbd5db2a6caae10f0ab2cf2625fbc34485a4ce9 (diff) | |
download | raidgrep-13053073e3336b8e6ffefd6a056d159239550be7.tar.gz raidgrep-13053073e3336b8e6ffefd6a056d159239550be7.tar.bz2 raidgrep-13053073e3336b8e6ffefd6a056d159239550be7.zip |
Merge branch 'new-filters'
The new filter system (includes both the internal rewrite and the
command line parsing) is now being included in master. This gives a lot
more flexibility.
Diffstat (limited to 'src/fexpr/mod.rs')
-rw-r--r-- | src/fexpr/mod.rs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/fexpr/mod.rs b/src/fexpr/mod.rs new file mode 100644 index 0000000..5610aba --- /dev/null +++ b/src/fexpr/mod.rs @@ -0,0 +1,66 @@ +//! Filter expression language. +//! +//! This module contains methods to parse a given string into an abstract filter tree, check its +//! type and convert it to a [`Filter`][super::filters::Filter]. +// Make it available in the grammar mod. +use super::{filters, FightOutcome, SearchField, Weekday}; + +use std::{error, fmt}; + +use lalrpop_util::{lalrpop_mod, lexer::Token, ParseError}; +use thiserror::Error; + +lalrpop_mod!(#[allow(clippy::all)] pub grammar, "/fexpr/grammar.rs"); + +#[derive(Debug)] +pub struct FError { + location: usize, + data: String, + kind: FErrorKind, +} + +impl fmt::Display for FError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} (at {})", self.kind, self.location) + } +} + +impl error::Error for FError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(&self.kind) + } +} + +#[derive(Debug, Error)] +pub enum FErrorKind { + #[error("invalid regular expression: {0}")] + InvalidRegex(#[from] regex::Error), + #[error("invalid fight outcome")] + InvalidFightOutcome, + #[error("invalid weekday")] + InvalidWeekday, + #[error("invalid timestamp: {0}")] + InvalidTimestamp(#[from] chrono::format::ParseError), + #[error("invalid boss name")] + InvalidBoss, +} + +/// Shortcut to create a new parser and parse the given input. +pub fn parse_logfilter<'a>( + input: &'a str, +) -> Result<Box<dyn filters::log::LogFilter>, ParseError<usize, Token<'a>, FError>> { + grammar::LogFilterParser::new().parse(input) +} + +/// Extract the location from the given error. +pub fn location<T>(err: &ParseError<usize, T, FError>) -> usize { + match *err { + ParseError::InvalidToken { location } => location, + ParseError::UnrecognizedEOF { location, .. } => location, + ParseError::UnrecognizedToken { + token: (l, _, _), .. + } => l, + ParseError::ExtraToken { token: (l, _, _) } => l, + ParseError::User { ref error } => error.location, + } +} |