131 lines
3.4 KiB
Rust
131 lines
3.4 KiB
Rust
pub mod crit_graph;
|
|
pub mod crit_leaf;
|
|
pub mod crit_matchers;
|
|
pub mod crit_per_target_data;
|
|
|
|
use {
|
|
crate::{
|
|
crit_graph::{CritMgr, CritMiddle, CritRoot, CritRootCriterion, CritRootFixed},
|
|
crit_leaf::CritLeafMatcher,
|
|
crit_matchers::{critm_any_or_all::CritMatchAnyOrAll, critm_exactly::CritMatchExactly},
|
|
},
|
|
jay_utils::{copyhashmap::CopyHashMap, numcell::NumCell},
|
|
linearize::StaticMap,
|
|
regex::Regex,
|
|
std::rc::{Rc, Weak},
|
|
};
|
|
pub use {
|
|
crit_graph::{CritTarget, CritUpstreamNode},
|
|
crit_per_target_data::CritDestroyListener,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub struct CritMatcherIds {
|
|
next: NumCell<u64>,
|
|
}
|
|
|
|
impl Default for CritMatcherIds {
|
|
fn default() -> Self {
|
|
Self {
|
|
next: NumCell::new(1),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl CritMatcherIds {
|
|
pub fn next(&self) -> CritMatcherId {
|
|
CritMatcherId(self.next.fetch_add(1))
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
|
pub struct CritMatcherId(u64);
|
|
|
|
impl CritMatcherId {
|
|
#[allow(clippy::allow_attributes, dead_code)]
|
|
pub fn raw(&self) -> u64 {
|
|
self.0
|
|
}
|
|
|
|
#[allow(clippy::allow_attributes, dead_code)]
|
|
pub fn from_raw(id: u64) -> Self {
|
|
Self(id)
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for CritMatcherId {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
std::fmt::Display::fmt(&self.0, f)
|
|
}
|
|
}
|
|
|
|
pub type RootMatcherMap<Target, T> = CopyHashMap<CritMatcherId, Weak<CritRoot<Target, T>>>;
|
|
pub type FixedRootMatcher<Target, T> =
|
|
StaticMap<bool, Rc<CritRoot<Target, CritRootFixed<Target, T>>>>;
|
|
|
|
#[derive(Clone)]
|
|
pub enum CritLiteralOrRegex {
|
|
Literal(String),
|
|
Regex(Regex),
|
|
}
|
|
|
|
impl CritLiteralOrRegex {
|
|
fn matches(&self, string: &str) -> bool {
|
|
match self {
|
|
CritLiteralOrRegex::Literal(p) => string == p,
|
|
CritLiteralOrRegex::Regex(r) => r.is_match(string),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait CritMgrExt: CritMgr {
|
|
fn list(
|
|
&self,
|
|
upstream: &[Rc<dyn CritUpstreamNode<Self::Target>>],
|
|
all: bool,
|
|
) -> Rc<dyn CritUpstreamNode<Self::Target>> {
|
|
if upstream.is_empty() {
|
|
return self.match_constant()[all].clone();
|
|
}
|
|
CritMiddle::new(self, upstream, CritMatchAnyOrAll::new(upstream, all))
|
|
}
|
|
|
|
fn exactly(
|
|
&self,
|
|
upstream: &[Rc<dyn CritUpstreamNode<Self::Target>>],
|
|
num: usize,
|
|
) -> Rc<dyn CritUpstreamNode<Self::Target>> {
|
|
if num > upstream.len() {
|
|
return self.match_constant()[false].clone();
|
|
}
|
|
if num == 0 {
|
|
let upstream: Vec<_> = upstream.iter().map(|u| u.not(self)).collect();
|
|
return self.list(&upstream, true);
|
|
}
|
|
CritMiddle::new(self, upstream, CritMatchExactly::new(upstream, num))
|
|
}
|
|
|
|
fn leaf(
|
|
&self,
|
|
upstream: &Rc<dyn CritUpstreamNode<Self::Target>>,
|
|
on_match: impl Fn(<Self::Target as CritTarget>::LeafData) -> Box<dyn FnOnce()> + 'static,
|
|
) -> Rc<CritLeafMatcher<Self::Target>> {
|
|
CritLeafMatcher::new(self, upstream, on_match)
|
|
}
|
|
|
|
fn not(
|
|
&self,
|
|
upstream: &Rc<dyn CritUpstreamNode<Self::Target>>,
|
|
) -> Rc<dyn CritUpstreamNode<Self::Target>> {
|
|
upstream.not(self)
|
|
}
|
|
|
|
fn root<T>(&self, criterion: T) -> Rc<dyn CritUpstreamNode<Self::Target>>
|
|
where
|
|
T: CritRootCriterion<Self::Target>,
|
|
{
|
|
CritRoot::new(self.roots(), self.id(), criterion)
|
|
}
|
|
}
|
|
|
|
impl<T> CritMgrExt for T where T: CritMgr {}
|