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