use std::cell::RefCell;
use std::rc::Rc;
use std::sync::{
Arc,
Mutex,
};
use qubit_function::{
ArcPredicate,
ArcStatefulFunction,
BoxPredicate,
BoxStatefulFunction,
FunctionOnce,
RcPredicate,
RcStatefulFunction,
StatefulFunction,
};
#[derive(Clone)]
struct CustomStatefulFunction {
multiplier: i32,
}
impl StatefulFunction<i32, i32> for CustomStatefulFunction {
fn apply(&mut self, input: &i32) -> i32 {
self.multiplier += 1;
input * self.multiplier
}
}
#[test]
fn test_stateful_function_trait_apply() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let func = move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x + current
};
assert_eq!(func.clone().apply(&10), 10);
assert_eq!(func.clone().apply(&10), 11);
assert_eq!(func.apply(&10), 12);
}
#[test]
fn test_box_stateful_function_new() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = BoxStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x + current
});
assert_eq!(func.apply(&10), 10);
assert_eq!(func.apply(&10), 11);
assert_eq!(func.apply(&10), 12);
}
#[test]
fn test_box_stateful_function_identity() {
let mut identity = BoxStatefulFunction::<i32, i32>::identity();
assert_eq!(identity.apply(&42), 42);
assert_eq!(identity.apply(&0), 0);
assert_eq!(identity.apply(&-100), -100);
}
#[test]
fn test_box_stateful_function_constant() {
let mut constant = BoxStatefulFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
assert_eq!(constant.apply(&0), "hello");
}
#[test]
fn test_box_stateful_function_apply() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = BoxStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x * current
});
assert_eq!(func.apply(&10), 0);
assert_eq!(func.apply(&10), 10);
assert_eq!(func.apply(&10), 20);
}
#[test]
fn test_box_stateful_function_and_then() {
let mut counter1 = 0;
let func1 = BoxStatefulFunction::new(move |x: &i32| {
counter1 += 1;
x + counter1
});
let mut counter2 = 0;
let func2 = BoxStatefulFunction::new(move |x: &i32| {
counter2 += 1;
x * counter2
});
let mut composed = func1.and_then(func2);
assert_eq!(composed.apply(&10), 11); assert_eq!(composed.apply(&10), 24); }
#[test]
fn test_box_stateful_function_when_or_else() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = BoxStatefulFunction::new(move |x: &i32| {
*counter_clone.borrow_mut() += 1;
x * 2
})
.when(|x: &i32| *x > 10)
.or_else(|x: &i32| x + 1);
assert_eq!(func.apply(&15), 30); assert_eq!(func.apply(&5), 6); assert_eq!(*counter.borrow(), 1); }
#[test]
fn test_box_stateful_function_when_with_predicate() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = BoxStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x * current
})
.when(BoxPredicate::new(|x: &i32| *x > 0))
.or_else(|x: &i32| -(*x));
assert_eq!(func.apply(&10), 0); assert_eq!(func.apply(&-5), 5); }
#[test]
fn test_arc_stateful_function_new() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let mut func = ArcStatefulFunction::new(move |x: &i32| {
let mut current =
counter_clone.lock().expect("mutex should not be poisoned");
let result = x + *current;
*current += 1;
result
});
assert_eq!(func.apply(&10), 10);
assert_eq!(func.apply(&10), 11);
assert_eq!(func.apply(&10), 12);
}
#[test]
fn test_arc_stateful_function_identity() {
let mut identity = ArcStatefulFunction::<i32, i32>::identity();
assert_eq!(identity.apply(&42), 42);
assert_eq!(identity.apply(&0), 0);
assert_eq!(identity.apply(&-100), -100);
}
#[test]
fn test_arc_stateful_function_constant() {
let mut constant = ArcStatefulFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
}
#[test]
fn test_arc_stateful_function_apply() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let mut func = ArcStatefulFunction::new(move |x: &i32| {
let mut current =
counter_clone.lock().expect("mutex should not be poisoned");
let result = x * *current;
*current += 1;
result
});
assert_eq!(func.apply(&10), 0);
assert_eq!(func.apply(&10), 10);
}
#[test]
fn test_arc_stateful_function_clone() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let func = ArcStatefulFunction::new(move |x: &i32| {
let mut current =
counter_clone.lock().expect("mutex should not be poisoned");
let result = x + *current;
*current += 1;
result
});
let mut func_clone = func.clone();
assert_eq!(func_clone.apply(&10), 10);
assert_eq!(func_clone.apply(&10), 11);
}
#[test]
fn test_arc_stateful_function_and_then() {
let mut counter1 = 0;
let func1 = ArcStatefulFunction::new(move |x: &i32| {
counter1 += 1;
x + counter1
});
let mut counter2 = 0;
let func2 = ArcStatefulFunction::new(move |x: &i32| {
counter2 += 1;
x * counter2
});
let mut composed = func1.and_then(func2);
assert_eq!(composed.apply(&10), 11); assert_eq!(composed.apply(&10), 24); }
#[test]
fn test_arc_stateful_function_when_or_else() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let mut func = ArcStatefulFunction::new(move |x: &i32| {
*counter_clone.lock().expect("mutex should not be poisoned") += 1;
x * 2
})
.when(|x: &i32| *x > 10)
.or_else(|x: &i32| x + 1);
assert_eq!(func.apply(&15), 30); assert_eq!(func.apply(&5), 6); assert_eq!(*counter.lock().expect("mutex should not be poisoned"), 1); }
#[test]
fn test_arc_stateful_function_when_with_predicate() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let mut func = ArcStatefulFunction::new(move |x: &i32| {
let mut current =
counter_clone.lock().expect("mutex should not be poisoned");
let result = x * *current;
*current += 1;
result
})
.when(ArcPredicate::new(|x: &i32| *x > 0))
.or_else(|x: &i32| -(*x));
assert_eq!(func.apply(&10), 0); assert_eq!(func.apply(&-5), 5); }
#[test]
fn test_arc_stateful_function_thread_safety() {
let counter = Arc::new(Mutex::new(0));
let counter_clone = Arc::clone(&counter);
let func = ArcStatefulFunction::new(move |x: &i32| {
let mut current =
counter_clone.lock().expect("mutex should not be poisoned");
let result = x + *current;
*current += 1;
result
});
let mut func_clone = func.clone();
let handle = std::thread::spawn(move || func_clone.apply(&10));
assert_eq!(handle.join().expect("thread should not panic"), 10);
}
#[test]
fn test_rc_stateful_function_new() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = RcStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x + current
});
assert_eq!(func.apply(&10), 10);
assert_eq!(func.apply(&10), 11);
assert_eq!(func.apply(&10), 12);
}
#[test]
fn test_rc_stateful_function_identity() {
let mut identity = RcStatefulFunction::<i32, i32>::identity();
assert_eq!(identity.apply(&42), 42);
assert_eq!(identity.apply(&0), 0);
assert_eq!(identity.apply(&-100), -100);
}
#[test]
fn test_rc_stateful_function_constant() {
let mut constant = RcStatefulFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
}
#[test]
fn test_rc_stateful_function_apply() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = RcStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x * current
});
assert_eq!(func.apply(&10), 0);
assert_eq!(func.apply(&10), 10);
}
#[test]
fn test_rc_stateful_function_clone() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let func = RcStatefulFunction::new(move |x: &i32| {
let current = *counter_clone.borrow();
*counter_clone.borrow_mut() += 1;
x + current
});
let mut func_clone = func.clone();
assert_eq!(func_clone.apply(&10), 10);
assert_eq!(func_clone.apply(&10), 11);
}
#[test]
fn test_rc_stateful_function_and_then() {
let mut counter1 = 0;
let func1 = RcStatefulFunction::new(move |x: &i32| {
counter1 += 1;
x + counter1
});
let mut counter2 = 0;
let func2 = RcStatefulFunction::new(move |x: &i32| {
counter2 += 1;
x * counter2
});
let mut composed = func1.and_then(func2);
assert_eq!(composed.apply(&10), 11); assert_eq!(composed.apply(&10), 24); }
#[test]
fn test_rc_stateful_function_when_or_else() {
let counter = Rc::new(RefCell::new(0));
let counter_clone = Rc::clone(&counter);
let mut func = RcStatefulFunction::new(move |x: &i32| {
*counter_clone.borrow_mut() += 1;
x * 2
})
.when(|x: &i32| *x > 10)
.or_else(|x: &i32| x + 1);
assert_eq!(func.apply(&15), 30); assert_eq!(func.apply(&5), 6); assert_eq!(*counter.borrow(), 1); }