use std::sync::Arc;
use caramelo::{
MatchType::{self, To},
Matcher, TypedMatcher,
};
pub fn and<T: Send + Sync + 'static>(
matchers: Vec<Arc<dyn TypedMatcher<T> + Send + Sync + 'static>>,
) -> Arc<dyn TypedMatcher<T> + Send + Sync + 'static> {
Arc::new(And { matchers })
}
pub struct And<T: Send + Sync + 'static> {
matchers: Vec<Arc<dyn TypedMatcher<T> + Send + Sync + 'static>>,
}
unsafe impl<T: Send + Sync + 'static> Send for And<T> {}
unsafe impl<T: Send + Sync + 'static> Sync for And<T> {}
impl<T: Send + Sync + 'static> And<T> {
pub fn new(matchers: Vec<Arc<dyn TypedMatcher<T> + Send + Sync + 'static>>) -> Self {
And { matchers }
}
}
impl<T> Matcher<T> for And<T>
where
T: Send + Sync + 'static,
{
fn matches(&self, value: &T) -> bool {
self.matchers
.iter()
.all(|m| m.matches(value))
}
fn description(&self) -> String {
self.matchers
.iter()
.map(|m| m.description())
.collect::<Vec<_>>()
.join(" and ")
}
}
impl<T> TypedMatcher<T> for And<T>
where
T: Send + Sync + 'static,
{
fn matcher_type(&self) -> MatchType {
self.matchers
.first()
.map(|m| TypedMatcher::matcher_type(m.as_ref()))
.unwrap_or(To)
}
}