use std::ops::Not;
use std::rc::Rc;
use super::ALWAYS_FALSE_NAME;
use super::ALWAYS_TRUE_NAME;
use crate::Predicate;
use crate::predicates::macros::impl_predicate_clone;
use crate::predicates::macros::impl_predicate_common_methods;
use crate::predicates::macros::impl_predicate_debug_display;
use crate::predicates::macros::impl_shared_predicate_methods;
#[must_use = "callback wrappers do nothing unless stored or invoked"]
pub struct RcPredicate<T> {
pub(super) function: Rc<dyn Fn(&T) -> bool>,
pub(super) metadata: crate::internal::CallbackMetadata,
}
impl<T> RcPredicate<T> {
impl_predicate_common_methods!(
RcPredicate<T>,
semantic(Predicate<T> + 'static),
|predicate| move |value: &T| predicate.test(value),
|f| Rc::new(f)
);
impl_shared_predicate_methods!(RcPredicate<T>, 'static);
}
impl<T> Not for RcPredicate<T>
where
T: 'static,
{
type Output = RcPredicate<T>;
fn not(self) -> Self::Output {
let metadata = self.metadata;
let function = self.function;
RcPredicate::new_with_metadata(move |value: &T| !function(value), metadata)
}
}
impl<T> Not for &RcPredicate<T>
where
T: 'static,
{
type Output = RcPredicate<T>;
fn not(self) -> Self::Output {
let function = self.function.clone();
RcPredicate::new_with_metadata(move |value: &T| !function(value), self.metadata.clone())
}
}
impl_predicate_clone!(RcPredicate<T>);
impl_predicate_debug_display!(RcPredicate<T>);
impl<T> Predicate<T> for RcPredicate<T> {
#[inline]
fn test(&self, value: &T) -> bool {
(self.function)(value)
}
}