1
0
Fork 0
forked from wry/wry

criteria: add infrastructure

This commit is contained in:
Julian Orth 2025-05-02 16:52:04 +02:00
parent 597636fba6
commit 17e715cde4
18 changed files with 1214 additions and 3 deletions

View 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(),
}
}
}

View 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
}
}

View 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(),
}
}
}

View 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))
}
}