criteria: add infrastructure
This commit is contained in:
parent
597636fba6
commit
17e715cde4
18 changed files with 1214 additions and 3 deletions
73
src/criteria/crit_matchers/critm_any_or_all.rs
Normal file
73
src/criteria/crit_matchers/critm_any_or_all.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use {
|
||||
crate::criteria::crit_graph::{CritMiddleCriterion, CritTarget, CritUpstreamNode},
|
||||
std::{marker::PhantomData, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct CritMatchAnyOrAll<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
all: bool,
|
||||
total: usize,
|
||||
_phantom: PhantomData<fn(&Target)>,
|
||||
}
|
||||
|
||||
impl<Target> CritMatchAnyOrAll<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
pub fn new(upstream: &[Rc<dyn CritUpstreamNode<Target>>], all: bool) -> Self {
|
||||
Self {
|
||||
all,
|
||||
total: upstream.len(),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Target> CritMiddleCriterion<Target> for CritMatchAnyOrAll<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
type Data = usize;
|
||||
type Not = Self;
|
||||
|
||||
fn update_matched(&self, _data: &Target, node: &mut usize, matched: bool) -> bool {
|
||||
if matched {
|
||||
*node += 1;
|
||||
} else {
|
||||
*node -= 1;
|
||||
}
|
||||
if self.all {
|
||||
*node == self.total
|
||||
} else {
|
||||
*node > 0
|
||||
}
|
||||
}
|
||||
|
||||
fn pull(&self, upstream: &[Rc<dyn CritUpstreamNode<Target>>], node: &Target) -> bool {
|
||||
for upstream in upstream {
|
||||
if upstream.pull(node) {
|
||||
if !self.all {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if self.all {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.all
|
||||
}
|
||||
|
||||
fn not(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self {
|
||||
all: !self.all,
|
||||
total: self.total,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/criteria/crit_matchers/critm_constant.rs
Normal file
59
src/criteria/crit_matchers/critm_constant.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
use {
|
||||
crate::criteria::{
|
||||
CritMatcherIds, FixedRootMatcher,
|
||||
crit_graph::{
|
||||
CritFixedRootCriterion, CritFixedRootCriterionBase, CritMgr, CritRoot, CritRootFixed,
|
||||
CritTarget,
|
||||
},
|
||||
},
|
||||
linearize::static_map,
|
||||
std::{marker::PhantomData, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct CritMatchConstant<Target>(pub bool, pub PhantomData<fn(&Target)>);
|
||||
|
||||
impl<Target> CritMatchConstant<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
#[expect(dead_code)]
|
||||
pub fn create(
|
||||
roots: &Rc<Target::RootMatchers>,
|
||||
ids: &CritMatcherIds,
|
||||
) -> FixedRootMatcher<Target, CritMatchConstant<Target>> {
|
||||
static_map! {
|
||||
v => CritRoot::new(
|
||||
roots,
|
||||
ids.next(),
|
||||
CritRootFixed(Self(v, PhantomData), PhantomData),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Target> CritFixedRootCriterionBase<Target> for CritMatchConstant<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
fn constant(&self) -> bool {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn not<'a>(&self, mgr: &'a Target::Mgr) -> &'a FixedRootMatcher<Target, Self>
|
||||
where
|
||||
Self: CritFixedRootCriterion<Target>,
|
||||
{
|
||||
mgr.match_constant()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Target> CritFixedRootCriterion<Target> for CritMatchConstant<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
const COMPARE: bool = false;
|
||||
|
||||
fn matches(&self, _data: &Target) -> bool {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
61
src/criteria/crit_matchers/critm_exactly.rs
Normal file
61
src/criteria/crit_matchers/critm_exactly.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
use {
|
||||
crate::criteria::crit_graph::{CritMiddleCriterion, CritTarget, CritUpstreamNode},
|
||||
std::{marker::PhantomData, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct CritMatchExactly<Target> {
|
||||
total: usize,
|
||||
num: usize,
|
||||
not: bool,
|
||||
_phantom: PhantomData<fn(&Target)>,
|
||||
}
|
||||
|
||||
impl<Target> CritMatchExactly<Target> {
|
||||
pub fn new(upstream: &[Rc<dyn CritUpstreamNode<Target>>], num: usize) -> Self {
|
||||
Self {
|
||||
total: upstream.len(),
|
||||
num,
|
||||
not: false,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Target> CritMiddleCriterion<Target> for CritMatchExactly<Target>
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
type Data = usize;
|
||||
type Not = Self;
|
||||
|
||||
fn update_matched(&self, _data: &Target, node: &mut usize, matched: bool) -> bool {
|
||||
if matched {
|
||||
*node += 1;
|
||||
} else {
|
||||
*node -= 1;
|
||||
}
|
||||
(*node == self.num) ^ self.not
|
||||
}
|
||||
|
||||
fn pull(&self, upstream: &[Rc<dyn CritUpstreamNode<Target>>], node: &Target) -> bool {
|
||||
let mut n = 0;
|
||||
for upstream in upstream {
|
||||
if upstream.pull(node) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
(n == self.num) ^ self.not
|
||||
}
|
||||
|
||||
fn not(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self {
|
||||
total: self.total,
|
||||
num: self.total - self.num,
|
||||
not: !self.not,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/criteria/crit_matchers/critm_string.rs
Normal file
46
src/criteria/crit_matchers/critm_string.rs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
use {
|
||||
crate::criteria::{
|
||||
CritLiteralOrRegex, RootMatcherMap,
|
||||
crit_graph::{CritRootCriterion, CritTarget},
|
||||
},
|
||||
std::marker::PhantomData,
|
||||
};
|
||||
|
||||
pub struct CritMatchString<Target, A> {
|
||||
string: CritLiteralOrRegex,
|
||||
_phantom: PhantomData<(fn(&Target), A)>,
|
||||
}
|
||||
|
||||
pub trait StringAccess<Target>: Sized + 'static
|
||||
where
|
||||
Target: CritTarget,
|
||||
{
|
||||
fn with_string(data: &Target, f: impl FnOnce(&str) -> bool) -> bool;
|
||||
fn nodes(
|
||||
roots: &Target::RootMatchers,
|
||||
) -> &RootMatcherMap<Target, CritMatchString<Target, Self>>;
|
||||
}
|
||||
|
||||
impl<Target, A> CritMatchString<Target, A> {
|
||||
#[expect(dead_code)]
|
||||
pub fn new(string: CritLiteralOrRegex) -> Self {
|
||||
Self {
|
||||
string,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Target, A> CritRootCriterion<Target> for CritMatchString<Target, A>
|
||||
where
|
||||
Target: CritTarget,
|
||||
A: StringAccess<Target>,
|
||||
{
|
||||
fn matches(&self, data: &Target) -> bool {
|
||||
A::with_string(data, |s| self.string.matches(s))
|
||||
}
|
||||
|
||||
fn nodes(roots: &Target::RootMatchers) -> Option<&RootMatcherMap<Target, Self>> {
|
||||
Some(A::nodes(roots))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue