use std::ops::Not;
use super::{
Arc,
BoxTester,
Rc,
RcTester,
Tester,
};
pub struct ArcTester {
pub(super) function: Arc<dyn Fn() -> bool + Send + Sync>,
}
impl ArcTester {
#[inline]
pub fn new<F>(f: F) -> Self
where
F: Fn() -> bool + Send + Sync + 'static,
{
ArcTester {
function: Arc::new(f),
}
}
#[inline]
pub fn and(&self, next: &ArcTester) -> ArcTester {
let self_fn = Arc::clone(&self.function);
let next_fn = Arc::clone(&next.function);
ArcTester {
function: Arc::new(move || self_fn() && next_fn()),
}
}
#[inline]
pub fn or(&self, next: &ArcTester) -> ArcTester {
let self_fn = Arc::clone(&self.function);
let next_fn = Arc::clone(&next.function);
ArcTester {
function: Arc::new(move || self_fn() || next_fn()),
}
}
#[inline]
pub fn nand(&self, next: &ArcTester) -> ArcTester {
let self_fn = Arc::clone(&self.function);
let next_fn = Arc::clone(&next.function);
ArcTester {
function: Arc::new(move || !(self_fn() && next_fn())),
}
}
#[inline]
pub fn xor(&self, next: &ArcTester) -> ArcTester {
let self_fn = Arc::clone(&self.function);
let next_fn = Arc::clone(&next.function);
ArcTester {
function: Arc::new(move || self_fn() ^ next_fn()),
}
}
#[inline]
pub fn nor(&self, next: &ArcTester) -> ArcTester {
let self_fn = Arc::clone(&self.function);
let next_fn = Arc::clone(&next.function);
ArcTester {
function: Arc::new(move || !(self_fn() || next_fn())),
}
}
}
impl Not for ArcTester {
type Output = ArcTester;
#[inline]
fn not(self) -> Self::Output {
let func = self.function;
ArcTester {
function: Arc::new(move || !func()),
}
}
}
impl Not for &ArcTester {
type Output = ArcTester;
#[inline]
fn not(self) -> Self::Output {
let func = Arc::clone(&self.function);
ArcTester {
function: Arc::new(move || !func()),
}
}
}
impl Tester for ArcTester {
#[inline]
fn test(&self) -> bool {
(self.function)()
}
#[inline]
fn into_box(self) -> BoxTester {
let func = self.function;
BoxTester {
function: Box::new(move || func()),
}
}
#[inline]
fn into_rc(self) -> RcTester {
let func = self.function;
RcTester {
function: Rc::new(move || func()),
}
}
#[inline]
fn into_arc(self) -> ArcTester {
self
}
#[inline]
fn into_fn(self) -> impl Fn() -> bool {
move || (self.function)()
}
#[inline]
fn to_box(&self) -> BoxTester {
let self_fn = self.function.clone();
BoxTester {
function: Box::new(move || self_fn()),
}
}
#[inline]
fn to_rc(&self) -> RcTester {
let self_fn = self.function.clone();
RcTester {
function: Rc::new(move || self_fn()),
}
}
#[inline]
fn to_arc(&self) -> ArcTester {
self.clone()
}
#[inline]
fn to_fn(&self) -> impl Fn() -> bool {
let self_fn = self.function.clone();
move || self_fn()
}
}
impl Clone for ArcTester {
#[inline]
fn clone(&self) -> Self {
Self {
function: Arc::clone(&self.function),
}
}
}