use qubit_function::{
ArcFunction,
ArcPredicate,
BoxFunction,
BoxPredicate,
Function,
FunctionOnce,
Predicate,
RcFunction,
RcPredicate,
};
#[test]
fn test_function_trait_apply() {
let double = |x: &i32| x * 2;
assert_eq!(double.apply(&21), 42);
assert_eq!(double.apply(&0), 0);
assert_eq!(double.apply(&-10), -20);
}
#[test]
fn test_function_trait_into_box() {
let double = |x: &i32| x * 2;
let boxed = Function::into_box(double);
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_function_trait_into_rc() {
let double = |x: &i32| x * 2;
let rc = double.into_rc();
assert_eq!(rc.apply(&21), 42);
}
#[test]
fn test_function_trait_into_arc() {
let double = |x: &i32| x * 2;
let arc = double.into_arc();
assert_eq!(arc.apply(&21), 42);
}
#[test]
fn test_function_trait_into_fn() {
let double = |x: &i32| x * 2;
let func = Function::into_fn(double);
assert_eq!(func(&21), 42);
}
#[test]
fn test_function_trait_to_box() {
let double = |x: &i32| x * 2;
let boxed = Function::to_box(&double);
assert_eq!(boxed.apply(&21), 42);
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_function_trait_to_rc() {
let double = |x: &i32| x * 2;
let rc = double.to_rc();
assert_eq!(rc.apply(&21), 42);
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_function_trait_to_arc() {
let double = |x: &i32| x * 2;
let arc = double.to_arc();
assert_eq!(arc.apply(&21), 42);
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_function_trait_to_fn() {
let double = |x: &i32| x * 2;
let func = Function::to_fn(&double);
assert_eq!(func(&21), 42);
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_box_function_new_allows_non_static_t() {
fn run<'a>(value: &'a str) -> usize {
let func: BoxFunction<&'a str, usize> = BoxFunction::new(|x: &&'a str| x.len());
func.apply(&value)
}
let text = String::from("hello");
assert_eq!(run(text.as_str()), 5);
}
#[test]
fn test_box_function_new_allows_non_static_r() {
fn run<'a>(value: &'a str) -> &'a str {
let func: BoxFunction<&'a str, &'a str> = BoxFunction::new(|x: &&'a str| *x);
func.apply(&value)
}
let text = String::from("qubit");
assert_eq!(run(text.as_str()), "qubit");
}
#[test]
fn test_rc_function_new_allows_non_static_t() {
fn run<'a>(value: &'a str) -> usize {
let func: RcFunction<&'a str, usize> = RcFunction::new(|x: &&'a str| x.len());
func.apply(&value)
}
let text = String::from("hello");
assert_eq!(run(text.as_str()), 5);
}
#[test]
fn test_arc_function_new_allows_non_static_t() {
fn run<'a>(value: &'a str) -> usize {
let func: ArcFunction<&'a str, usize> = ArcFunction::new(|x: &&'a str| x.len() + 1);
func.apply(&value)
}
let text = String::from("hello");
assert_eq!(run(text.as_str()), 6);
}
#[test]
fn test_rc_function_new_allows_non_static_r() {
fn run<'a>(value: &'a str) -> &'a str {
let func: RcFunction<&'a str, &'a str> = RcFunction::new(|x: &&'a str| *x);
func.apply(&value)
}
let text = String::from("qubit");
assert_eq!(run(text.as_str()), "qubit");
}
#[test]
fn test_box_function_new() {
let double = BoxFunction::new(|x: &i32| x * 2);
assert_eq!(double.apply(&21), 42);
assert_eq!(double.apply(&0), 0);
assert_eq!(double.apply(&-5), -10);
}
#[test]
fn test_box_function_identity() {
let identity = BoxFunction::<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_function_constant() {
let constant = BoxFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
assert_eq!(constant.apply(&0), "hello");
}
#[test]
fn test_box_function_apply() {
let add_one = BoxFunction::new(|x: &i32| x + 1);
assert_eq!(add_one.apply(&41), 42);
assert_eq!(add_one.apply(&0), 1);
assert_eq!(add_one.apply(&-1), 0);
}
#[test]
fn test_box_function_and_then() {
let double = BoxFunction::new(|x: &i32| x * 2);
let to_string = BoxFunction::new(|x: &i32| x.to_string());
let composed = double.and_then(to_string);
assert_eq!(composed.apply(&21), "42");
assert_eq!(composed.apply(&0), "0");
assert_eq!(composed.apply(&-5), "-10");
}
#[test]
fn test_box_function_and_then_with_closure() {
let double = BoxFunction::new(|x: &i32| x * 2);
let composed = double.and_then(|x: &i32| x + 10);
assert_eq!(composed.apply(&16), 42);
}
#[test]
fn test_box_function_when_or_else() {
let double = BoxFunction::new(|x: &i32| x * 2);
let identity = BoxFunction::<i32, i32>::identity();
let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
assert_eq!(conditional.apply(&5), 10); assert_eq!(conditional.apply(&-5), -5); assert_eq!(conditional.apply(&0), 0); }
#[test]
fn test_box_function_when_with_closure() {
let double = BoxFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x >= 10).or_else(|x: &i32| *x);
assert_eq!(conditional.apply(&15), 30); assert_eq!(conditional.apply(&5), 5); }
#[test]
fn test_box_function_when_with_predicate() {
let double = BoxFunction::new(|x: &i32| x * 2);
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
let conditional = double.when(is_positive).or_else(|x: &i32| -(*x));
assert_eq!(conditional.apply(&5), 10); assert_eq!(conditional.apply(&-5), 5); }
#[test]
fn test_box_function_once_impl_into_box() {
let double = BoxFunction::new(|x: &i32| x * 2);
let boxed = double.into_box();
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_box_function_into_rc() {
let double = BoxFunction::new(|x: &i32| x * 2);
let rc = double.into_rc();
assert_eq!(rc.apply(&21), 42);
}
#[test]
fn test_box_function_once_impl_into_fn() {
let double = BoxFunction::new(|x: &i32| x * 2);
let func = double.into_fn();
assert_eq!(func(&21), 42);
}
#[test]
fn test_box_function_once_impl_apply() {
let double = BoxFunction::new(|x: &i32| x * 2);
let result = double.apply(&21);
assert_eq!(result, 42);
}
#[test]
fn test_arc_function_new() {
let double = ArcFunction::new(|x: &i32| x * 2);
assert_eq!(double.apply(&21), 42);
assert_eq!(double.apply(&0), 0);
assert_eq!(double.apply(&-5), -10);
}
#[test]
fn test_arc_function_identity() {
let identity = ArcFunction::<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_function_constant() {
let constant = ArcFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
}
#[test]
fn test_arc_function_once_impl_apply() {
let add_one = ArcFunction::new(|x: &i32| x + 1);
assert_eq!(add_one.apply(&41), 42);
assert_eq!(add_one.apply(&0), 1);
}
#[test]
fn test_arc_function_clone() {
let double = ArcFunction::new(|x: &i32| x * 2);
let cloned = double.clone();
assert_eq!(double.apply(&21), 42);
assert_eq!(cloned.apply(&21), 42);
}
#[test]
fn test_arc_function_and_then() {
let double = ArcFunction::new(|x: &i32| x * 2);
let to_string = ArcFunction::new(|x: &i32| x.to_string());
let composed = double.and_then(to_string);
assert_eq!(composed.apply(&21), "42");
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_arc_function_and_then_with_clone() {
let double = ArcFunction::new(|x: &i32| x * 2);
let to_string = ArcFunction::new(|x: &i32| x.to_string());
let composed = double.and_then(to_string.clone());
assert_eq!(composed.apply(&21), "42");
assert_eq!(to_string.apply(&5), "5");
}
#[test]
fn test_arc_function_when_or_else() {
let double = ArcFunction::new(|x: &i32| x * 2);
let identity = ArcFunction::<i32, i32>::identity();
let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
let conditional_clone = conditional.clone();
assert_eq!(conditional.apply(&5), 10);
assert_eq!(conditional_clone.apply(&-5), -5);
}
#[test]
fn test_arc_function_when_with_predicate() {
let double = ArcFunction::new(|x: &i32| x * 2);
let is_positive = ArcPredicate::new(|x: &i32| *x > 0);
let conditional = double
.when(is_positive.clone())
.or_else(ArcFunction::identity());
assert_eq!(conditional.apply(&5), 10);
assert!(is_positive.test(&3));
}
#[test]
fn test_arc_function_once_impl_into_box() {
let double = ArcFunction::new(|x: &i32| x * 2);
let boxed = double.into_box();
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_arc_function_into_rc() {
let double = ArcFunction::new(|x: &i32| x * 2);
let rc = double.into_rc();
assert_eq!(rc.apply(&21), 42);
}
#[test]
fn test_arc_function_into_arc() {
let double = ArcFunction::new(|x: &i32| x * 2);
let arc = double.into_arc();
assert_eq!(arc.apply(&21), 42);
}
#[test]
fn test_arc_function_once_impl_into_fn() {
let double = ArcFunction::new(|x: &i32| x * 2);
let func = double.into_fn();
assert_eq!(func(&21), 42);
}
#[test]
fn test_arc_function_once_impl_to_box() {
let double = ArcFunction::new(|x: &i32| x * 2);
let boxed = double.to_box();
assert_eq!(boxed.apply(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_arc_function_to_rc() {
let double = ArcFunction::new(|x: &i32| x * 2);
let rc = double.to_rc();
assert_eq!(rc.apply(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_arc_function_to_arc() {
let double = ArcFunction::new(|x: &i32| x * 2);
let arc = double.to_arc();
assert_eq!(arc.apply(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_arc_function_once_impl_to_fn() {
let double = ArcFunction::new(|x: &i32| x * 2);
let func = double.to_fn();
assert_eq!(func(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_arc_function_send_sync() {
let double = ArcFunction::new(|x: &i32| x * 2);
let double_clone = double.clone();
let handle = std::thread::spawn(move || double_clone.apply(&21));
assert_eq!(handle.join().unwrap(), 42);
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_rc_function_new() {
let double = RcFunction::new(|x: &i32| x * 2);
assert_eq!(double.apply(&21), 42);
assert_eq!(double.apply(&0), 0);
assert_eq!(double.apply(&-5), -10);
}
#[test]
fn test_rc_function_identity() {
let identity = RcFunction::<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_function_constant() {
let constant = RcFunction::constant("hello");
assert_eq!(constant.apply(&123), "hello");
assert_eq!(constant.apply(&456), "hello");
}
#[test]
fn test_rc_function_once_impl_apply() {
let add_one = RcFunction::new(|x: &i32| x + 1);
assert_eq!(add_one.apply(&41), 42);
assert_eq!(add_one.apply(&0), 1);
}
#[test]
fn test_rc_function_clone() {
let double = RcFunction::new(|x: &i32| x * 2);
let cloned = double.clone();
assert_eq!(double.apply(&21), 42);
assert_eq!(cloned.apply(&21), 42);
}
#[test]
fn test_rc_function_and_then() {
let double = RcFunction::new(|x: &i32| x * 2);
let to_string = RcFunction::new(|x: &i32| x.to_string());
let composed = double.and_then(to_string);
assert_eq!(composed.apply(&21), "42");
assert_eq!(double.apply(&10), 20);
}
#[test]
fn test_rc_function_and_then_with_clone() {
let double = RcFunction::new(|x: &i32| x * 2);
let to_string = RcFunction::new(|x: &i32| x.to_string());
let composed = double.and_then(to_string.clone());
assert_eq!(composed.apply(&21), "42");
assert_eq!(to_string.apply(&5), "5");
}
#[test]
fn test_rc_function_when_or_else() {
let double = RcFunction::new(|x: &i32| x * 2);
let identity = RcFunction::<i32, i32>::identity();
let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
let conditional_clone = conditional.clone();
assert_eq!(conditional.apply(&5), 10);
assert_eq!(conditional_clone.apply(&-5), -5);
}
#[test]
fn test_rc_function_when_with_predicate() {
let double = RcFunction::new(|x: &i32| x * 2);
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let conditional = double
.when(is_positive.clone())
.or_else(RcFunction::<i32, i32>::identity());
assert_eq!(conditional.apply(&5), 10);
assert!(is_positive.test(&3));
}
#[test]
fn test_rc_function_once_impl_into_box() {
let double = RcFunction::new(|x: &i32| x * 2);
let boxed = double.into_box();
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_rc_function_into_rc() {
let double = RcFunction::new(|x: &i32| x * 2);
let rc = double.into_rc();
assert_eq!(rc.apply(&21), 42);
}
#[test]
fn test_rc_function_once_impl_into_fn() {
let double = RcFunction::new(|x: &i32| x * 2);
let func = double.into_fn();
assert_eq!(func(&21), 42);
}
#[test]
fn test_rc_function_once_impl_to_box() {
let double = RcFunction::new(|x: &i32| x * 2);
let boxed = double.to_box();
assert_eq!(boxed.apply(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_rc_function_to_rc() {
let double = RcFunction::new(|x: &i32| x * 2);
let rc = double.to_rc();
assert_eq!(rc.apply(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_rc_function_once_impl_to_fn() {
let double = RcFunction::new(|x: &i32| x * 2);
let func = double.to_fn();
assert_eq!(func(&21), 42);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_function_with_zero() {
let double = BoxFunction::new(|x: &i32| x * 2);
assert_eq!(double.apply(&0), 0);
}
#[test]
fn test_function_with_negative() {
let double = BoxFunction::new(|x: &i32| x * 2);
assert_eq!(double.apply(&-42), -84);
}
#[test]
fn test_function_with_max_value() {
let identity = BoxFunction::<i32, i32>::identity();
assert_eq!(identity.apply(&i32::MAX), i32::MAX);
}
#[test]
fn test_function_with_min_value() {
let identity = BoxFunction::<i32, i32>::identity();
assert_eq!(identity.apply(&i32::MIN), i32::MIN);
}
#[test]
fn test_function_chain_multiple() {
let add_one = BoxFunction::new(|x: &i32| x + 1);
let double = BoxFunction::new(|x: &i32| x * 2);
let add_ten = BoxFunction::new(|x: &i32| x + 10);
let composed = add_one.and_then(double).and_then(add_ten);
assert_eq!(composed.apply(&5), 22); }
#[test]
fn test_function_with_string() {
let to_upper = BoxFunction::new(|s: &String| s.to_uppercase());
let input = String::from("hello");
assert_eq!(to_upper.apply(&input), "HELLO");
}
#[test]
fn test_function_with_vec() {
let get_len = BoxFunction::new(|v: &Vec<i32>| v.len());
let vec = vec![1, 2, 3, 4, 5];
assert_eq!(get_len.apply(&vec), 5);
}
#[test]
fn test_function_with_option() {
let unwrap_or_zero = BoxFunction::new(|opt: &Option<i32>| opt.unwrap_or(0));
assert_eq!(unwrap_or_zero.apply(&Some(42)), 42);
assert_eq!(unwrap_or_zero.apply(&None), 0);
}
#[test]
fn test_conditional_function_edge_cases() {
let double = BoxFunction::new(|x: &i32| x * 2);
let negate = BoxFunction::new(|x: &i32| -(*x));
let conditional = double.when(|x: &i32| *x >= 0).or_else(negate);
assert_eq!(conditional.apply(&0), 0); assert_eq!(conditional.apply(&1), 2); assert_eq!(conditional.apply(&-1), 1); }
#[test]
fn test_fn_function_ops_and_then() {
use qubit_function::FnFunctionOps;
let double = |x: &i32| x * 2;
let to_string = |x: &i32| x.to_string();
let composed = double.and_then(to_string);
assert_eq!(composed.apply(&21), "42");
}
#[test]
fn test_fn_function_ops_when() {
use qubit_function::FnFunctionOps;
let double = |x: &i32| x * 2;
let conditional = double.when(|x: &i32| *x > 0).or_else(|x: &i32| -(*x));
assert_eq!(conditional.apply(&5), 10);
assert_eq!(conditional.apply(&-5), 5);
}
#[test]
fn test_closure_function_into_once() {
let multiply = |x: &i32| x * 3;
let once_func = multiply.into_once();
assert_eq!(once_func.apply(&4), 12); }
#[test]
fn test_closure_function_to_once() {
let add_five = |x: &i32| x + 5;
let once_func = add_five.to_once();
assert_eq!(once_func.apply(&7), 12);
let another_once_func = add_five.to_once();
assert_eq!(another_once_func.apply(&3), 8); }
#[cfg(test)]
mod function_default_impl_tests {
use qubit_function::{
ArcFunction,
BoxFunction,
Function,
FunctionOnce,
};
struct CustomFunction {
multiplier: i32,
}
impl Function<i32, i32> for CustomFunction {
fn apply(&self, input: &i32) -> i32 {
input * self.multiplier
}
}
#[derive(Clone)]
struct CloneableCustomFunction {
multiplier: i32,
}
impl Function<i32, i32> for CloneableCustomFunction {
fn apply(&self, input: &i32) -> i32 {
input * self.multiplier
}
}
#[test]
fn test_custom_into_box() {
let custom = CustomFunction { multiplier: 3 };
let boxed = custom.into_box();
assert_eq!(boxed.apply(&7), 21);
assert_eq!(boxed.apply(&10), 30);
}
#[test]
fn test_custom_into_rc() {
let custom = CustomFunction { multiplier: 5 };
let rc = custom.into_rc();
assert_eq!(rc.apply(&4), 20);
assert_eq!(rc.apply(&6), 30);
let rc_clone = rc.clone();
assert_eq!(rc_clone.apply(&2), 10);
}
#[test]
fn test_custom_into_arc() {
let custom = CustomFunction { multiplier: 7 };
let arc = custom.into_arc();
assert_eq!(arc.apply(&3), 21);
assert_eq!(arc.apply(&5), 35);
let arc_clone = arc.clone();
assert_eq!(arc_clone.apply(&2), 14);
}
#[test]
fn test_custom_into_fn() {
let custom = CustomFunction { multiplier: 4 };
let func = custom.into_fn();
assert_eq!(func(&5), 20);
assert_eq!(func(&10), 40);
}
#[test]
fn test_cloneable_to_box() {
let custom = CloneableCustomFunction { multiplier: 3 };
let boxed = custom.to_box();
assert_eq!(boxed.apply(&7), 21);
assert_eq!(custom.apply(&10), 30);
}
#[test]
fn test_cloneable_to_rc() {
let custom = CloneableCustomFunction { multiplier: 5 };
let rc = custom.to_rc();
assert_eq!(rc.apply(&4), 20);
assert_eq!(custom.apply(&6), 30);
}
#[test]
fn test_cloneable_to_arc() {
let custom = CloneableCustomFunction { multiplier: 7 };
let arc = custom.to_arc();
assert_eq!(arc.apply(&3), 21);
assert_eq!(custom.apply(&5), 35);
}
#[test]
fn test_cloneable_to_fn() {
let custom = CloneableCustomFunction { multiplier: 4 };
let func = custom.to_fn();
assert_eq!(func(&5), 20);
assert_eq!(custom.apply(&10), 40);
}
#[test]
fn test_custom_chained_conversions() {
let custom1 = CustomFunction { multiplier: 2 };
let custom2 = CustomFunction { multiplier: 3 };
let boxed: BoxFunction<i32, i32> = custom1.into_box();
let rc = boxed.into_rc();
assert_eq!(rc.apply(&21), 42);
let arc: ArcFunction<i32, i32> = custom2.into_arc();
assert_eq!(arc.apply(&14), 42);
}
#[test]
fn test_custom_composition() {
let custom1 = CloneableCustomFunction { multiplier: 2 };
let custom2 = CloneableCustomFunction { multiplier: 3 };
let composed = custom1.to_box().and_then(custom2.to_box());
assert_eq!(composed.apply(&7), 42); }
#[test]
fn test_custom_function_into_once() {
struct CustomFunction {
multiplier: i32,
}
impl Function<i32, i32> for CustomFunction {
fn apply(&self, input: &i32) -> i32 {
input * self.multiplier
}
}
let custom_func = CustomFunction { multiplier: 3 };
let once_func = custom_func.into_once();
assert_eq!(once_func.apply(&5), 15); }
#[test]
fn test_cloneable_custom_function_to_once() {
#[derive(Clone)]
struct CloneableCustomFunction {
multiplier: i32,
}
impl Function<i32, i32> for CloneableCustomFunction {
fn apply(&self, input: &i32) -> i32 {
input * self.multiplier
}
}
let custom_func = CloneableCustomFunction { multiplier: 4 };
let once_func = custom_func.to_once();
assert_eq!(once_func.apply(&6), 24);
let another_once_func = custom_func.to_once();
assert_eq!(another_once_func.apply(&2), 8); }
}
#[test]
fn test_arc_conditional_function_clone() {
let double = ArcFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x > 0);
let conditional_clone = conditional.clone();
let result1 = conditional.or_else(|x: &i32| -(*x));
let result2 = conditional_clone.or_else(|x: &i32| x + 100);
assert_eq!(result1.apply(&5), 10); assert_eq!(result1.apply(&-5), 5); assert_eq!(result2.apply(&5), 10); assert_eq!(result2.apply(&-5), 95); }
#[test]
fn test_arc_conditional_function_clone_multiple() {
let triple = ArcFunction::new(|x: &i32| x * 3);
let conditional = triple.when(|x: &i32| *x % 2 == 0);
let clone1 = conditional.clone();
let clone2 = conditional.clone();
let clone3 = conditional.clone();
let result1 = conditional.or_else(|x: &i32| *x);
let result2 = clone1.or_else(|x: &i32| *x);
let result3 = clone2.or_else(|x: &i32| *x);
let result4 = clone3.or_else(|x: &i32| *x);
assert_eq!(result1.apply(&4), 12); assert_eq!(result2.apply(&4), 12);
assert_eq!(result3.apply(&4), 12);
assert_eq!(result4.apply(&4), 12);
assert_eq!(result1.apply(&5), 5); assert_eq!(result2.apply(&5), 5);
assert_eq!(result3.apply(&5), 5);
assert_eq!(result4.apply(&5), 5);
}
#[test]
fn test_box_conditional_function_debug_display() {
let double = BoxFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x > 0);
let debug_str = format!("{:?}", conditional);
assert!(debug_str.contains("BoxConditionalFunction"));
assert!(debug_str.contains("name"));
assert!(debug_str.contains("function"));
assert!(debug_str.contains("predicate"));
let display_str = format!("{}", conditional);
assert!(display_str.starts_with("BoxConditionalFunction("));
assert!(display_str.contains("BoxFunction"));
assert!(display_str.contains("BoxPredicate"));
assert!(display_str.ends_with(")"));
let triple = BoxFunction::new_with_name("triple_func", |x: &i32| x * 3);
let named_conditional = triple.when(|x: &i32| *x % 2 == 0);
let named_debug_str = format!("{:?}", named_conditional);
assert!(named_debug_str.contains("BoxConditionalFunction"));
assert!(named_debug_str.contains("name"));
assert!(named_debug_str.contains("function"));
assert!(named_debug_str.contains("predicate"));
let named_display_str = format!("{}", named_conditional);
assert!(named_display_str.starts_with("BoxConditionalFunction("));
assert!(named_display_str.contains("BoxFunction(triple_func)"));
assert!(named_display_str.contains("BoxPredicate"));
assert!(named_display_str.ends_with(")"));
}
#[test]
fn test_rc_conditional_function_debug_display() {
let double = RcFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x > 0);
let debug_str = format!("{:?}", conditional);
assert!(debug_str.contains("RcConditionalFunction"));
assert!(debug_str.contains("name"));
assert!(debug_str.contains("function"));
assert!(debug_str.contains("predicate"));
let display_str = format!("{}", conditional);
assert!(display_str.starts_with("RcConditionalFunction("));
assert!(display_str.contains("RcFunction"));
assert!(display_str.contains("RcPredicate"));
assert!(display_str.ends_with(")"));
let triple = RcFunction::new_with_name("rc_triple_func", |x: &i32| x * 3);
let named_conditional = triple.when(|x: &i32| *x % 2 == 0);
let named_debug_str = format!("{:?}", named_conditional);
assert!(named_debug_str.contains("RcConditionalFunction"));
assert!(named_debug_str.contains("name"));
assert!(named_debug_str.contains("function"));
assert!(named_debug_str.contains("predicate"));
let named_display_str = format!("{}", named_conditional);
assert!(named_display_str.starts_with("RcConditionalFunction("));
assert!(named_display_str.contains("RcFunction(rc_triple_func)"));
assert!(named_display_str.contains("RcPredicate"));
assert!(named_display_str.ends_with(")"));
}
#[test]
fn test_arc_conditional_function_debug_display() {
let double = ArcFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x > 0);
let debug_str = format!("{:?}", conditional);
assert!(debug_str.contains("ArcConditionalFunction"));
assert!(debug_str.contains("name"));
assert!(debug_str.contains("function"));
assert!(debug_str.contains("predicate"));
let display_str = format!("{}", conditional);
assert!(display_str.starts_with("ArcConditionalFunction("));
assert!(display_str.contains("ArcFunction"));
assert!(display_str.contains("ArcPredicate"));
assert!(display_str.ends_with(")"));
let triple = ArcFunction::new_with_name("arc_triple_func", |x: &i32| x * 3);
let named_conditional = triple.when(|x: &i32| *x % 2 == 0);
let named_debug_str = format!("{:?}", named_conditional);
assert!(named_debug_str.contains("ArcConditionalFunction"));
assert!(named_debug_str.contains("name"));
assert!(named_debug_str.contains("function"));
assert!(named_debug_str.contains("predicate"));
let named_display_str = format!("{}", named_conditional);
assert!(named_display_str.starts_with("ArcConditionalFunction("));
assert!(named_display_str.contains("ArcFunction(arc_triple_func)"));
assert!(named_display_str.contains("ArcPredicate"));
assert!(named_display_str.ends_with(")"));
}
#[test]
fn test_rc_conditional_function_clone() {
let double = RcFunction::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x > 0);
let conditional_clone = conditional.clone();
let result1 = conditional.or_else(|x: &i32| -(*x));
let result2 = conditional_clone.or_else(|x: &i32| x + 100);
assert_eq!(result1.apply(&5), 10); assert_eq!(result1.apply(&-5), 5); assert_eq!(result2.apply(&5), 10); assert_eq!(result2.apply(&-5), 95); }
#[test]
fn test_rc_conditional_function_clone_multiple() {
let triple = RcFunction::new(|x: &i32| x * 3);
let conditional = triple.when(|x: &i32| *x % 2 == 0);
let clone1 = conditional.clone();
let clone2 = conditional.clone();
let clone3 = conditional.clone();
let result1 = conditional.or_else(|x: &i32| *x);
let result2 = clone1.or_else(|x: &i32| *x);
let result3 = clone2.or_else(|x: &i32| *x);
let result4 = clone3.or_else(|x: &i32| *x);
assert_eq!(result1.apply(&4), 12); assert_eq!(result2.apply(&4), 12);
assert_eq!(result3.apply(&4), 12);
assert_eq!(result4.apply(&4), 12);
assert_eq!(result1.apply(&5), 5); assert_eq!(result2.apply(&5), 5);
assert_eq!(result3.apply(&5), 5);
assert_eq!(result4.apply(&5), 5);
}
#[test]
fn test_rc_function_into_box_preserves_name() {
let original = RcFunction::new_with_name("test_rc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_rc_func"));
let boxed = original.into_box();
assert_eq!(boxed.name(), Some("test_rc_func"));
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_arc_function_into_box_preserves_name() {
let original = ArcFunction::new_with_name("test_arc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_arc_func"));
let boxed = original.into_box();
assert_eq!(boxed.name(), Some("test_arc_func"));
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_arc_function_into_rc_preserves_name() {
let original = ArcFunction::new_with_name("test_arc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_arc_func"));
let rc = original.into_rc();
assert_eq!(rc.name(), Some("test_arc_func"));
assert_eq!(rc.apply(&21), 42);
}
#[test]
fn test_rc_function_to_box_preserves_name() {
let original = RcFunction::new_with_name("test_rc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_rc_func"));
let boxed = original.to_box();
assert_eq!(boxed.name(), Some("test_rc_func"));
assert_eq!(boxed.apply(&21), 42);
assert_eq!(original.apply(&21), 42);
}
#[test]
fn test_arc_function_to_box_preserves_name() {
let original = ArcFunction::new_with_name("test_arc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_arc_func"));
let boxed = original.to_box();
assert_eq!(boxed.name(), Some("test_arc_func"));
assert_eq!(boxed.apply(&21), 42);
assert_eq!(original.apply(&21), 42);
}
#[test]
fn test_arc_function_to_rc_preserves_name() {
let original = ArcFunction::new_with_name("test_arc_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("test_arc_func"));
let rc = original.to_rc();
assert_eq!(rc.name(), Some("test_arc_func"));
assert_eq!(rc.apply(&21), 42);
assert_eq!(original.apply(&21), 42);
}
#[test]
fn test_function_conversions_without_name() {
let original = RcFunction::new(|x: &i32| x * 2);
assert_eq!(original.name(), None);
let boxed = original.into_box();
assert_eq!(boxed.name(), None);
assert_eq!(boxed.apply(&21), 42);
}
#[test]
fn test_multiple_conversions_preserve_name() {
let original = ArcFunction::new_with_name("original_func", |x: &i32| x * 2);
assert_eq!(original.name(), Some("original_func"));
let rc = original.to_rc();
assert_eq!(rc.name(), Some("original_func"));
assert_eq!(rc.apply(&21), 42);
let boxed = rc.to_box();
assert_eq!(boxed.name(), Some("original_func"));
assert_eq!(boxed.apply(&21), 42);
assert_eq!(original.apply(&21), 42);
}