diff --git a/Cargo.lock b/Cargo.lock index c64531c5..bcd442f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -738,7 +738,7 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hl" -version = "0.25.3-alpha.2" +version = "0.25.3-alpha.3" dependencies = [ "atoi", "bincode", diff --git a/Cargo.toml b/Cargo.toml index dcb331f6..c1e10dec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ categories = ["command-line-utilities"] description = "Utility for viewing json-formatted log files." keywords = ["cli", "human", "log"] name = "hl" -version = "0.25.3-alpha.2" +version = "0.25.3-alpha.3" edition = "2021" build = "build.rs" diff --git a/src/app.rs b/src/app.rs index c174fbf9..14f98fe3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -26,20 +26,21 @@ use sha2::{Digest, Sha256}; use std::num::{NonZeroU32, NonZeroUsize}; // local imports -use crate::datefmt::{DateTimeFormat, DateTimeFormatter}; use crate::{error::*, QueryNone}; +use crate::datefmt::{DateTimeFormat, DateTimeFormatter}; use crate::fmtx::aligned_left; -use crate::fsmon::{self, EventKind}; use crate::formatting::{RecordFormatter, RecordWithSourceFormatter, RawRecordFormatter}; +use crate::fsmon::{self, EventKind}; +use crate::IncludeExcludeKeyFilter; use crate::index::{Indexer, Timestamp}; use crate::input::{BlockLine, InputHolder, InputReference, Input}; use crate::model::{Filter, Parser, ParserSettings, RawRecord, Record, RecordFilter, RecordWithSourceConstructor}; +use crate::query::Query; use crate::scanning::{BufFactory, Scanner, Segment, SegmentBuf, SegmentBufFactory}; use crate::serdex::StreamDeserializerWithOffsets; use crate::settings::{Fields, Formatting}; use crate::theme::{Element, StylingPush, Theme}; use crate::timezone::Tz; -use crate::IncludeExcludeKeyFilter; // TODO: merge Options to Settings and replace Options with Settings. @@ -80,8 +81,6 @@ impl Options { } } -type Query = Box; - pub struct FieldOptions { pub filter: Arc, pub settings: Fields, diff --git a/src/main.rs b/src/main.rs index 1710e295..ce45ef7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -381,9 +381,9 @@ fn run() -> Result<()> { let mut query: Option = None; for q in opt.query { - let right = hl::query::parse(&q)?; + let right = Query::parse(&q)?; if let Some(left) = query { - query = Some(hl::query::and(left, right)); + query = Some(left.and(right)); } else { query = Some(right); } diff --git a/src/query.rs b/src/query.rs index 5b5791b6..1968db23 100644 --- a/src/query.rs +++ b/src/query.rs @@ -19,23 +19,43 @@ use crate::types::FieldKind; #[grammar = "query.pest"] pub struct QueryParser; -pub type Query = Box; +pub struct Query { + filter: Box, +} -// --- +impl Query { + pub fn parse(str: &str) -> Result { + let mut pairs = QueryParser::parse(Rule::input, str)?; + Ok(expression(pairs.next().unwrap())?) + } -pub fn parse(str: &str) -> Result { - let mut pairs = QueryParser::parse(Rule::input, str)?; - Ok(expression(pairs.next().unwrap())?) -} + pub fn and(self, rhs: Query) -> Query { + Query::new(And { lhs: self, rhs }) + } + + pub fn or(self, rhs: Query) -> Query { + Query::new(Or { lhs: self, rhs }) + } -pub fn and(lhs: Query, rhs: Query) -> Query { - Box::new(And { lhs, rhs }) + pub fn not(self) -> Query { + Query::new(Not { arg: self }) + } + + fn new(filter: F) -> Self { + Self { + filter: Box::new(filter), + } + } } -pub fn or(lhs: Query, rhs: Query) -> Query { - Box::new(Or { lhs, rhs }) +impl RecordFilter for Query { + fn apply<'a>(&self, record: &'a Record<'a>) -> bool { + self.filter.apply(record) + } } +// --- + fn expression(pair: Pair) -> Result { match pair.as_rule() { Rule::expr_or => binary_op::(pair), @@ -50,7 +70,7 @@ fn binary_op(pair: Pair) -> Result { let mut inner = pair.into_inner(); let mut result = expression(inner.next().unwrap())?; for inner in inner { - result = Box::new(Op::new(result, expression(inner)?)); + result = Query::new(Op::new(result, expression(inner)?)); } Ok(result) } @@ -58,7 +78,7 @@ fn binary_op(pair: Pair) -> Result { fn not(pair: Pair) -> Result { assert_eq!(pair.as_rule(), Rule::expr_not); - Ok(Box::new(Not { + Ok(Query::new(Not { arg: expression(pair.into_inner().next().unwrap())?, })) } @@ -124,7 +144,7 @@ fn field_filter(pair: Pair) -> Result { _ => unreachable!(), }; - Ok(Box::new(FieldFilter::new( + Ok(Query::new(FieldFilter::new( parse_field_name(lhs)?.borrowed(), match_policy, if negated { @@ -276,7 +296,7 @@ impl bool + Send + Sync + 'static> LevelFilter { } fn query(f: F) -> Query { - Box::new(Self::new(f)) + Query::new(Self::new(f)) } }