Refactor field filters to share same base parse node

This commit is contained in:
NGnius (Graham) 2023-07-09 15:30:22 -04:00
parent 00812bb3a3
commit 7dbd896348
9 changed files with 247 additions and 151 deletions

View file

@ -6,21 +6,25 @@ pub(crate) fn standard_vocab(vocabulary: &mut LanguageDictionary) {
// filters // filters
.add(crate::lang::vocabulary::filters::empty_filter()) .add(crate::lang::vocabulary::filters::empty_filter())
.add(crate::lang::vocabulary::filters::unique_filter()) // accepts .(unique) .add(crate::lang::vocabulary::filters::unique_filter()) // accepts .(unique)
.add(crate::lang::vocabulary::filters::field_filter()) // accepts any .(something)
.add(crate::lang::vocabulary::filters::field_filter_maybe())
.add(crate::lang::vocabulary::filters::index_filter())
.add(crate::lang::vocabulary::filters::range_filter()) .add(crate::lang::vocabulary::filters::range_filter())
.add(crate::lang::vocabulary::filters::field_like_filter()) .add( // accepts any .(.something)
.add(crate::lang::vocabulary::filters::field_re_filter()) crate::lang::vocabulary::filters::field::FieldFilterBlockFactory::new()
.push(crate::lang::vocabulary::filters::field::FieldFilterComparisonFactory)
.push(crate::lang::vocabulary::filters::field::FieldFilterMaybeFactory)
.push(crate::lang::vocabulary::filters::field::FieldLikeFilterFactory)
.push(crate::lang::vocabulary::filters::field::FieldRegexFilterFactory)
.to_statement_factory()
)
.add(crate::lang::vocabulary::filters::index_filter())
.add(crate::lang::vocabulary::filters::unique_field_filter()) .add(crate::lang::vocabulary::filters::unique_field_filter())
.add(crate::lang::vocabulary::filters::nonempty_filter()) .add(crate::lang::vocabulary::filters::nonempty_filter())
// sorters // sorters
.add(crate::lang::vocabulary::sorters::empty_sort()) .add(crate::lang::vocabulary::sorters::empty_sort())
.add(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(shuffle) .add(crate::lang::vocabulary::sorters::shuffle_sort()) // accepts ~(~shuffle)
.add(crate::lang::vocabulary::sorters::bliss_sort()) .add(crate::lang::vocabulary::sorters::bliss_sort())
.add(crate::lang::vocabulary::sorters::bliss_next_sort()) .add(crate::lang::vocabulary::sorters::bliss_next_sort())
.add(crate::lang::vocabulary::sorters::radio_sort()) .add(crate::lang::vocabulary::sorters::radio_sort())
.add(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(name) .add(crate::lang::vocabulary::sorters::field_sort()) // accepts any ~(.name)
// iter blocks // iter blocks
.add( .add(
crate::lang::ItemBlockFactory::new() crate::lang::ItemBlockFactory::new()

View file

@ -1,11 +1,11 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt::{Debug, Display, Error, Formatter}; use std::fmt::{Debug, Display, Error, Formatter};
use super::utility::{assert_comparison_operator, comparison_op}; use super::super::utility::{assert_comparison_operator, comparison_op};
use crate::lang::utility::{assert_token, assert_type, check_is_type, assert_token_raw}; use super::{FieldFilterFactory, FieldFilterPredicate};
use crate::lang::utility::{assert_token, assert_type, check_is_type};
use crate::lang::LanguageDictionary; use crate::lang::LanguageDictionary;
use crate::lang::TypePrimitive; use crate::lang::TypePrimitive;
use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory};
use crate::lang::{RuntimeMsg, SyntaxError}; use crate::lang::{RuntimeMsg, SyntaxError};
use crate::processing::general::Type; use crate::processing::general::Type;
use crate::tokens::Token; use crate::tokens::Token;
@ -46,7 +46,7 @@ impl Display for FieldFilter {
} }
} }
impl FilterPredicate for FieldFilter { impl FieldFilterPredicate for FieldFilter {
fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> { fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> {
let variable = match &self.val { let variable = match &self.val {
VariableOrValue::Variable(name) => match ctx.variables.get(name)? { VariableOrValue::Variable(name) => match ctx.variables.get(name)? {
@ -93,41 +93,33 @@ impl FilterPredicate for FieldFilter {
fn reset(&mut self) -> Result<(), RuntimeMsg> { fn reset(&mut self) -> Result<(), RuntimeMsg> {
Ok(()) Ok(())
} }
fn box_clone(&self) -> Box<dyn FieldFilterPredicate + 'static> {
Box::new(self.clone())
}
} }
pub struct FieldFilterFactory; pub struct FieldFilterComparisonFactory;
impl FilterFactory<FieldFilter> for FieldFilterFactory { impl FieldFilterFactory<FieldFilter> for FieldFilterComparisonFactory {
fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { fn is_filter(&self, tokens: &[Token]) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 (tokens_len >= 1
// .field > variable OR .field < variable // .field > variable OR .field < variable
&& tokens[0].is_dot() && (tokens[0].is_open_angle_bracket() || tokens[0].is_close_angle_bracket()))
&& tokens[1].is_name() || (tokens_len >= 2 // .field >= variable OR .field <= variable OR .field != variable OR .field == variable
&& (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket())) && (tokens[0].is_open_angle_bracket() || tokens[0].is_close_angle_bracket() || tokens[0].is_equals() || tokens[0].is_exclamation())
|| (tokens_len >= 4 // .field >= variable OR .field <= variable OR .field != variable OR .field == variable && tokens[1].is_equals()
&& tokens[0].is_dot() && !(tokens_len > 2 && tokens[2].is_equals())
&& tokens[1].is_name()
&& (tokens[2].is_open_angle_bracket() || tokens[2].is_close_angle_bracket() || tokens[2].is_equals() || tokens[2].is_exclamation())
&& tokens[3].is_equals()
&& !(tokens_len > 4 && tokens[4].is_equals())
) )
} }
fn build_filter( fn build_filter(
&self, &self,
tokens: &mut VecDeque<Token>, tokens: &mut VecDeque<Token>,
field: String,
_dict: &LanguageDictionary, _dict: &LanguageDictionary,
) -> Result<FieldFilter, SyntaxError> { ) -> Result<FieldFilter, SyntaxError> {
assert_token_raw(Token::Dot, tokens)?;
let field = assert_token(
|t| match t {
Token::Name(n) => Some(n),
_ => None,
},
Token::Name("field_name".into()),
tokens,
)?;
let compare_operator = assert_comparison_operator(tokens)?; let compare_operator = assert_comparison_operator(tokens)?;
if check_is_type(&tokens[0]) { if check_is_type(&tokens[0]) {
let value = VariableOrValue::Value(assert_type(tokens)?); let value = VariableOrValue::Value(assert_type(tokens)?);
@ -159,10 +151,3 @@ impl FilterFactory<FieldFilter> for FieldFilterFactory {
} }
} }
} }
pub type FieldFilterStatementFactory = FilterStatementFactory<FieldFilter, FieldFilterFactory>;
#[inline(always)]
pub fn field_filter() -> FieldFilterStatementFactory {
FieldFilterStatementFactory::new(FieldFilterFactory)
}

View file

@ -0,0 +1,160 @@
use std::collections::VecDeque;
use std::fmt::{Debug, Display, Error, Formatter};
use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory};
use crate::tokens::Token;
use crate::lang::utility::{assert_token, assert_token_raw};
use crate::lang::LanguageDictionary;
use crate::lang::{RuntimeMsg, SyntaxError};
use crate::Context;
use crate::Item;
pub trait FieldFilterFactory<T: FieldFilterPredicate + 'static>: Send + Sync {
fn is_filter(&self, tokens: &[Token]) -> bool;
fn build_filter(
&self,
tokens: &mut VecDeque<Token>,
field: String,
dict: &LanguageDictionary,
) -> Result<T, SyntaxError>;
}
pub trait FieldFilterPredicate: Send + Sync + Debug + Display {
fn matches(&mut self, item: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg>;
fn is_complete(&self) -> bool;
fn reset(&mut self) -> Result<(), RuntimeMsg>;
fn box_clone(&self) -> Box<dyn FieldFilterPredicate + 'static>;
}
pub struct FieldFilterFactoryBoxer<T: FieldFilterPredicate + 'static> {
inner: Box<dyn FieldFilterFactory<T>>
}
#[derive(Debug)]
pub struct BoxedFilterPredicate {
inner: Box<dyn FieldFilterPredicate + 'static>
}
impl Clone for BoxedFilterPredicate {
fn clone(&self) -> Self {
Self {
inner: self.inner.box_clone()
}
}
}
impl Display for BoxedFilterPredicate {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
(&self.inner as &dyn Display).fmt(f)
}
}
impl FilterPredicate for BoxedFilterPredicate {
fn matches(&mut self, item: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> {
self.inner.matches(item, ctx)
}
fn is_complete(&self) -> bool {
self.inner.is_complete()
}
fn reset(&mut self) -> Result<(), RuntimeMsg> {
self.inner.reset()
}
}
impl FieldFilterPredicate for BoxedFilterPredicate {
fn matches(&mut self, item: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> {
self.inner.matches(item, ctx)
}
fn is_complete(&self) -> bool {
self.inner.is_complete()
}
fn reset(&mut self) -> Result<(), RuntimeMsg> {
self.inner.reset()
}
fn box_clone(&self) -> Box<dyn FieldFilterPredicate + 'static> {
self.inner.box_clone()
}
}
impl <T: FieldFilterPredicate + 'static> FieldFilterFactory<BoxedFilterPredicate> for FieldFilterFactoryBoxer<T> {
fn is_filter(&self, tokens: &[Token]) -> bool {
self.inner.is_filter(tokens)
}
fn build_filter(
&self,
tokens: &mut VecDeque<Token>,
field: String,
dict: &LanguageDictionary,
) -> Result<BoxedFilterPredicate, SyntaxError> {
self.inner.build_filter(tokens, field, dict).map(|x| BoxedFilterPredicate { inner: Box::new(x) })
}
}
pub struct FieldFilterBlockFactory {
field_filters: Vec<Box<dyn FieldFilterFactory<BoxedFilterPredicate>>>,
}
impl FieldFilterBlockFactory {
pub fn new() -> Self {
Self {
field_filters: Vec::new(),
}
}
pub fn push<T: FieldFilterPredicate + 'static, F: FieldFilterFactory<T> + 'static>(mut self, factory: F) -> Self {
self.field_filters.push(
Box::new(FieldFilterFactoryBoxer { inner: Box::new(factory) })
);
self
}
#[inline(always)]
pub fn to_statement_factory(self) -> FieldFilterStatementFactory {
FieldFilterStatementFactory::new(self)
}
}
impl FilterFactory<BoxedFilterPredicate> for FieldFilterBlockFactory {
fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool {
tokens.len() > 1 && tokens[0].is_dot()
}
fn build_filter(
&self,
tokens: &mut VecDeque<Token>,
dict: &LanguageDictionary,
) -> Result<BoxedFilterPredicate, SyntaxError> {
assert_token_raw(Token::Dot, tokens)?;
let field = assert_token(
|t| match t {
Token::Name(n) => Some(n),
_ => None,
},
Token::Name("field_name".into()),
tokens,
)?;
for filter in &self.field_filters {
if filter.is_filter(tokens.make_contiguous()) {
return filter.build_filter(tokens, field, dict);
}
}
Err(SyntaxError {
got: tokens.front().cloned(),
token: Token::Name("<comparison op>".into()),
line: 0,
})
}
}
pub type FieldFilterStatementFactory =
FilterStatementFactory<BoxedFilterPredicate, FieldFilterBlockFactory>;

View file

@ -1,45 +1,34 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use super::utility::assert_comparison_operator; use super::super::utility::assert_comparison_operator;
use super::{field_filter::VariableOrValue, FieldFilter, FieldFilterErrorHandling}; use super::{field_filter::VariableOrValue, FieldFilter, FieldFilterErrorHandling};
use crate::lang::utility::{assert_token, assert_token_raw, assert_type, check_is_type}; use crate::lang::utility::{assert_token, assert_token_raw, assert_type, check_is_type};
use crate::lang::LanguageDictionary; use crate::lang::LanguageDictionary;
use crate::lang::SyntaxError; use crate::lang::SyntaxError;
use crate::lang::{FilterFactory, FilterStatementFactory}; //use crate::lang::{FilterFactory, FilterStatementFactory};
use super::FieldFilterFactory;
use crate::tokens::Token; use crate::tokens::Token;
pub struct FieldFilterMaybeFactory; pub struct FieldFilterMaybeFactory;
impl FilterFactory<FieldFilter> for FieldFilterMaybeFactory { impl FieldFilterFactory<FieldFilter> for FieldFilterMaybeFactory {
fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { fn is_filter(&self, tokens: &[Token]) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 4 // .field > variable OR .field < variable (tokens_len >= 2 // .field > variable OR .field < variable
&& tokens[0].is_dot() && (tokens[0].is_interrogation() || tokens[0].is_exclamation())
&& tokens[1].is_name() && (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket()))
&& (tokens[2].is_interrogation() || tokens[2].is_exclamation()) || (tokens_len >= 3 // .field >= variable OR .field <= variable OR .field != variable OR .field == variable
&& (tokens[3].is_open_angle_bracket() || tokens[3].is_close_angle_bracket())) && (tokens[0].is_interrogation() || tokens[0].is_exclamation())
|| (tokens_len >= 5 // .field >= variable OR .field <= variable OR .field != variable OR .field == variable && (tokens[1].is_open_angle_bracket() || tokens[1].is_close_angle_bracket() || tokens[1].is_equals() || tokens[1].is_exclamation())
&& tokens[0].is_dot() && tokens[2].is_equals())
&& tokens[1].is_name()
&& (tokens[2].is_interrogation() || tokens[2].is_exclamation())
&& (tokens[3].is_open_angle_bracket() || tokens[3].is_close_angle_bracket() || tokens[3].is_equals() || tokens[3].is_exclamation())
&& tokens[4].is_equals())
} }
fn build_filter( fn build_filter(
&self, &self,
tokens: &mut VecDeque<Token>, tokens: &mut VecDeque<Token>,
field: String,
_dict: &LanguageDictionary, _dict: &LanguageDictionary,
) -> Result<FieldFilter, SyntaxError> { ) -> Result<FieldFilter, SyntaxError> {
assert_token_raw(Token::Dot, tokens)?;
let field = assert_token(
|t| match t {
Token::Name(n) => Some(n),
_ => None,
},
Token::Name("field_name".into()),
tokens,
)?;
let error_f; let error_f;
let error_c; let error_c;
if tokens[0].is_interrogation() { if tokens[0].is_interrogation() {
@ -82,11 +71,3 @@ impl FilterFactory<FieldFilter> for FieldFilterMaybeFactory {
} }
} }
} }
pub type FieldFilterMaybeStatementFactory =
FilterStatementFactory<FieldFilter, FieldFilterMaybeFactory>;
#[inline(always)]
pub fn field_filter_maybe() -> FieldFilterMaybeStatementFactory {
FieldFilterMaybeStatementFactory::new(FieldFilterMaybeFactory)
}

View file

@ -5,7 +5,7 @@ use super::field_filter::{FieldFilterErrorHandling, VariableOrValue};
use crate::lang::utility::{assert_token, assert_token_raw, check_name}; use crate::lang::utility::{assert_token, assert_token_raw, check_name};
use crate::lang::LanguageDictionary; use crate::lang::LanguageDictionary;
use crate::lang::TypePrimitive; use crate::lang::TypePrimitive;
use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory}; use super::{FieldFilterFactory, FieldFilterPredicate};
use crate::lang::{RuntimeMsg, SyntaxError}; use crate::lang::{RuntimeMsg, SyntaxError};
use crate::processing::general::Type; use crate::processing::general::Type;
use crate::tokens::Token; use crate::tokens::Token;
@ -22,7 +22,7 @@ pub struct FieldLikeFilter {
impl FieldLikeFilter { impl FieldLikeFilter {
fn sanitise_string(s: &str) -> String { fn sanitise_string(s: &str) -> String {
super::utility::sanitise_string(s) super::super::utility::sanitise_string(s)
} }
} }
@ -35,7 +35,7 @@ impl Display for FieldLikeFilter {
} }
} }
impl FilterPredicate for FieldLikeFilter { impl FieldFilterPredicate for FieldLikeFilter {
fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> { fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> {
let variable = match &self.val { let variable = match &self.val {
VariableOrValue::Variable(name) => match ctx.variables.get(name)? { VariableOrValue::Variable(name) => match ctx.variables.get(name)? {
@ -74,38 +74,30 @@ impl FilterPredicate for FieldLikeFilter {
fn reset(&mut self) -> Result<(), RuntimeMsg> { fn reset(&mut self) -> Result<(), RuntimeMsg> {
Ok(()) Ok(())
} }
fn box_clone(&self) -> Box<dyn FieldFilterPredicate + 'static> {
Box::new(self.clone())
}
} }
pub struct FieldLikeFilterFactory; pub struct FieldLikeFilterFactory;
impl FilterFactory<FieldLikeFilter> for FieldLikeFilterFactory { impl FieldFilterFactory<FieldLikeFilter> for FieldLikeFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { fn is_filter(&self, tokens: &[Token]) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 // field like variable (tokens_len >= 1 // field like variable
&& tokens[0].is_dot() && (check_name("like", &tokens[0]) || check_name("unlike", &tokens[0])))
&& tokens[1].is_name() || (tokens_len >= 2 // field? like variable OR field! like variable
&& (check_name("like", tokens[2]) || check_name("unlike", tokens[2]))) && (tokens[0].is_interrogation() || tokens[0].is_exclamation())
|| (tokens_len >= 4 // field? like variable OR field! like variable && (check_name("like", &tokens[1]) || check_name("unlike", &tokens[1])))
&& tokens[0].is_dot()
&& tokens[1].is_name()
&& (tokens[2].is_interrogation() || tokens[2].is_exclamation())
&& (check_name("like", tokens[3]) || check_name("unlike", tokens[3])))
} }
fn build_filter( fn build_filter(
&self, &self,
tokens: &mut VecDeque<Token>, tokens: &mut VecDeque<Token>,
field: String,
_dict: &LanguageDictionary, _dict: &LanguageDictionary,
) -> Result<FieldLikeFilter, SyntaxError> { ) -> Result<FieldLikeFilter, SyntaxError> {
assert_token_raw(Token::Dot, tokens)?;
let field = assert_token(
|t| match t {
Token::Name(n) => Some(n),
_ => None,
},
Token::Name("field_name".into()),
tokens,
)?;
let error_handling = if tokens[0].is_interrogation() { let error_handling = if tokens[0].is_interrogation() {
assert_token_raw(Token::Interrogation, tokens)?; assert_token_raw(Token::Interrogation, tokens)?;
FieldFilterErrorHandling::Ignore FieldFilterErrorHandling::Ignore
@ -164,11 +156,3 @@ impl FilterFactory<FieldLikeFilter> for FieldLikeFilterFactory {
} }
} }
} }
pub type FieldLikeFilterStatementFactory =
FilterStatementFactory<FieldLikeFilter, FieldLikeFilterFactory>;
#[inline(always)]
pub fn field_like_filter() -> FieldLikeFilterStatementFactory {
FieldLikeFilterStatementFactory::new(FieldLikeFilterFactory)
}

View file

@ -7,7 +7,7 @@ use super::field_filter::{FieldFilterErrorHandling, VariableOrValue};
use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name}; use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name};
use crate::lang::LanguageDictionary; use crate::lang::LanguageDictionary;
use crate::lang::TypePrimitive; use crate::lang::TypePrimitive;
use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory}; use super::{FieldFilterFactory, FieldFilterPredicate};
use crate::lang::{RuntimeMsg, SyntaxError}; use crate::lang::{RuntimeMsg, SyntaxError};
use crate::processing::general::Type; use crate::processing::general::Type;
use crate::tokens::Token; use crate::tokens::Token;
@ -32,7 +32,7 @@ impl Display for FieldRegexFilter {
} }
} }
impl FilterPredicate for FieldRegexFilter { impl FieldFilterPredicate for FieldRegexFilter {
fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> { fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result<bool, RuntimeMsg> {
let variable = match &self.val { let variable = match &self.val {
VariableOrValue::Variable(name) => match ctx.variables.get(name)? { VariableOrValue::Variable(name) => match ctx.variables.get(name)? {
@ -83,38 +83,30 @@ impl FilterPredicate for FieldRegexFilter {
//self.regex_cache = None; //self.regex_cache = None;
Ok(()) Ok(())
} }
fn box_clone(&self) -> Box<dyn FieldFilterPredicate + 'static> {
Box::new(self.clone())
}
} }
pub struct FieldRegexFilterFactory; pub struct FieldRegexFilterFactory;
impl FilterFactory<FieldRegexFilter> for FieldRegexFilterFactory { impl FieldFilterFactory<FieldRegexFilter> for FieldRegexFilterFactory {
fn is_filter(&self, tokens: &VecDeque<&Token>) -> bool { fn is_filter(&self, tokens: &[Token]) -> bool {
let tokens_len = tokens.len(); let tokens_len = tokens.len();
(tokens_len >= 3 // .field like variable (tokens_len >= 1 // .field like variable
&& tokens[0].is_dot() && check_name("matches", &tokens[0]))
&& tokens[1].is_name() || (tokens_len >= 2 // .field? like variable OR .field! like variable
&& check_name("matches", tokens[2])) && (tokens[0].is_interrogation() || tokens[0].is_exclamation())
|| (tokens_len >= 4 // .field? like variable OR .field! like variable && check_name("matches", &tokens[1]))
&& tokens[0].is_dot()
&& tokens[1].is_name()
&& (tokens[2].is_interrogation() || tokens[2].is_exclamation())
&& check_name("matches", tokens[3]))
} }
fn build_filter( fn build_filter(
&self, &self,
tokens: &mut VecDeque<Token>, tokens: &mut VecDeque<Token>,
field: String,
_dict: &LanguageDictionary, _dict: &LanguageDictionary,
) -> Result<FieldRegexFilter, SyntaxError> { ) -> Result<FieldRegexFilter, SyntaxError> {
assert_token_raw(Token::Dot, tokens)?;
let field = assert_token(
|t| match t {
Token::Name(n) => Some(n),
_ => None,
},
Token::Name("field_name".into()),
tokens,
)?;
let error_handling = if tokens[0].is_interrogation() { let error_handling = if tokens[0].is_interrogation() {
assert_token_raw(Token::Interrogation, tokens)?; assert_token_raw(Token::Interrogation, tokens)?;
FieldFilterErrorHandling::Ignore FieldFilterErrorHandling::Ignore
@ -220,11 +212,3 @@ fn build_regex(pattern: &str, flags: u8) -> Result<Regex, regex::Error> {
.ignore_whitespace((flags & (1 << 5)) != 0) .ignore_whitespace((flags & (1 << 5)) != 0)
.build() .build()
} }
pub type FieldRegexFilterStatementFactory =
FilterStatementFactory<FieldRegexFilter, FieldRegexFilterFactory>;
#[inline(always)]
pub fn field_re_filter() -> FieldRegexFilterStatementFactory {
FieldRegexFilterStatementFactory::new(FieldRegexFilterFactory)
}

View file

@ -0,0 +1,14 @@
mod field_filter;
mod field_filter_factory;
mod field_filter_maybe;
mod field_like_filter;
mod field_match_filter;
pub use field_filter::{
FieldFilter, FieldFilterErrorHandling, FieldFilterComparisonFactory,
};
pub use field_filter_maybe::FieldFilterMaybeFactory;
pub use field_like_filter::FieldLikeFilterFactory;
pub use field_match_filter::FieldRegexFilterFactory;
pub use field_filter_factory::*;

View file

@ -1,8 +1,5 @@
mod empty_filter; mod empty_filter;
mod field_filter; pub mod field;
mod field_filter_maybe;
mod field_like_filter;
mod field_match_filter;
mod index_filter; mod index_filter;
mod nonempty_filter; mod nonempty_filter;
mod range_filter; mod range_filter;
@ -12,19 +9,6 @@ pub(crate) mod utility;
pub use empty_filter::{ pub use empty_filter::{
empty_filter, EmptyFilter, EmptyFilterFactory, EmptyFilterStatementFactory, empty_filter, EmptyFilter, EmptyFilterFactory, EmptyFilterStatementFactory,
}; };
pub use field_filter::{
field_filter, FieldFilter, FieldFilterErrorHandling, FieldFilterFactory,
FieldFilterStatementFactory,
};
pub use field_filter_maybe::{
field_filter_maybe, FieldFilterMaybeFactory, FieldFilterMaybeStatementFactory,
};
pub use field_like_filter::{
field_like_filter, FieldLikeFilterFactory, FieldLikeFilterStatementFactory,
};
pub use field_match_filter::{
field_re_filter, FieldRegexFilterFactory, FieldRegexFilterStatementFactory,
};
pub use index_filter::{ pub use index_filter::{
index_filter, IndexFilter, IndexFilterFactory, IndexFilterStatementFactory, index_filter, IndexFilter, IndexFilterFactory, IndexFilterStatementFactory,
}; };

View file

@ -1,7 +1,7 @@
use std::collections::{HashSet, VecDeque}; use std::collections::{HashSet, VecDeque};
use std::fmt::{Debug, Display, Error, Formatter}; use std::fmt::{Debug, Display, Error, Formatter};
use super::field_filter::FieldFilterErrorHandling; use super::field::FieldFilterErrorHandling;
use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name}; use crate::lang::utility::{assert_name, assert_token, assert_token_raw, check_name};
use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory}; use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory};
use crate::lang::{LanguageDictionary, TypePrimitive}; use crate::lang::{LanguageDictionary, TypePrimitive};