use qubit_function::{
ArcBiPredicate,
BiFunctionOnce,
BoxBiFunctionOnce,
BoxBiPredicate,
FnBiFunctionOnceOps,
RcBiPredicate,
};
#[test]
fn test_bi_function_once_trait_apply() {
let add = |x: &i32, y: &i32| *x + *y;
assert_eq!(add.apply(&21, &21), 42);
}
#[test]
fn test_bi_function_once_trait_apply_with_move() {
let value = String::from("hello");
let concat = move |x: &String, y: &String| format!("{} {} {}", x, value, y);
assert_eq!(
concat.apply(&String::from("world"), &String::from("!")),
"world hello !"
);
}
#[test]
fn test_bi_function_once_trait_apply_with_different_types() {
let multiply = |x: &i32, y: &f64| *x as f64 * *y;
assert_eq!(multiply.apply(&3, &2.5), 7.5);
}
#[test]
fn test_bi_function_once_trait_into_box() {
let add = |x: &i32, y: &i32| *x + *y;
let boxed = add.into_box();
assert_eq!(boxed.apply(&10, &15), 25);
}
#[test]
fn test_bi_function_once_trait_into_fn() {
let add = |x: &i32, y: &i32| *x + *y;
let func = add.into_fn();
assert_eq!(func(&10, &15), 25);
}
#[test]
fn test_bi_function_once_trait_to_box() {
let add = |x: &i32, y: &i32| *x + *y;
let boxed = add.to_box();
assert_eq!(boxed.apply(&8, &12), 20);
}
#[test]
fn test_bi_function_once_trait_to_fn() {
let add = |x: &i32, y: &i32| *x + *y;
let func = add.to_fn();
assert_eq!(func(&8, &12), 20);
}
#[test]
fn test_box_bi_function_once_new() {
let add = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
assert_eq!(add.apply(&5, &7), 12);
}
#[test]
fn test_box_bi_function_once_new_allows_non_static_t() {
fn run<'a>(value: &'a str) -> usize {
let func: BoxBiFunctionOnce<&'a str, i32, usize> =
BoxBiFunctionOnce::new(|x: &&'a str, y: &i32| x.len() + (*y as usize));
func.apply(&value, &3)
}
let text = String::from("hello");
assert_eq!(run(text.as_str()), 8);
}
#[test]
fn test_box_bi_function_once_new_allows_non_static_u() {
fn run<'a>(value: &'a str) -> usize {
let func: BoxBiFunctionOnce<i32, &'a str, usize> =
BoxBiFunctionOnce::new(|x: &i32, y: &&'a str| (*x as usize) + y.len());
func.apply(&3, &value)
}
let text = String::from("world");
assert_eq!(run(text.as_str()), 8);
}
#[test]
fn test_box_bi_function_once_new_allows_non_static_r() {
fn run<'a>(value: &'a str) -> &'a str {
let func: BoxBiFunctionOnce<&'a str, i32, &'a str> =
BoxBiFunctionOnce::new(|x: &&'a str, _y: &i32| *x);
func.apply(&value, &0)
}
let text = String::from("qubit");
assert_eq!(run(text.as_str()), "qubit");
}
#[test]
fn test_box_bi_function_once_new_with_name() {
let add = BoxBiFunctionOnce::new_with_name("adder", |x: &i32, y: &i32| *x + *y);
assert_eq!(add.name(), Some("adder"));
assert_eq!(add.apply(&3, &4), 7);
}
#[test]
fn test_box_bi_function_once_new_with_optional_name() {
let add1 = BoxBiFunctionOnce::new_with_optional_name(
|x: &i32, y: &i32| *x + *y,
Some("named".to_string()),
);
let add2 = BoxBiFunctionOnce::new_with_optional_name(|x: &i32, y: &i32| *x + *y, None);
assert_eq!(add1.name(), Some("named"));
assert_eq!(add2.name(), None);
assert_eq!(add1.apply(&2, &3), 5);
assert_eq!(add2.apply(&2, &3), 5);
}
#[test]
fn test_box_bi_function_once_name() {
let mut func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
assert_eq!(func.name(), None);
func.set_name("test");
assert_eq!(func.name(), Some("test"));
}
#[test]
fn test_box_bi_function_once_set_name() {
let mut func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
assert_eq!(func.name(), None);
func.set_name("multiplier");
assert_eq!(func.name(), Some("multiplier"));
func.set_name("new name");
assert_eq!(func.name(), Some("new name"));
}
#[test]
fn test_box_bi_function_once_constant() {
let constant_func1 = BoxBiFunctionOnce::constant(42);
let constant_func2 = BoxBiFunctionOnce::constant(42);
assert_eq!(constant_func1.apply(&1, &2), 42);
assert_eq!(constant_func2.apply(&10, &20), 42);
}
#[test]
fn test_box_bi_function_once_apply() {
let multiply = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x * *y);
assert_eq!(multiply.apply(&6, &7), 42);
}
#[test]
fn test_box_bi_function_once_into_box() {
let func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let boxed = func.into_box();
assert_eq!(boxed.apply(&1, &2), 3);
}
#[test]
fn test_box_bi_function_once_into_fn() {
let func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let closure = func.into_fn();
assert_eq!(closure(&1, &2), 3);
}
#[test]
fn test_box_bi_function_once_to_box_unavailable() {
let func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let boxed = func.into_box();
assert_eq!(boxed.apply(&5, &7), 12);
}
#[test]
fn test_box_bi_function_once_to_fn() {
}
#[test]
fn test_fn_bi_function_once_ops_and_then() {
let add = |x: &i32, y: &i32| *x + *y;
let double = |x: &i32| *x * 2;
let composed = add.and_then(double);
assert_eq!(composed.apply(&3, &4), 14); }
#[test]
fn test_fn_bi_function_once_ops_and_then_with_different_types() {
let concat = |x: &String, y: &String| format!("{} {}", x, y);
let length = |s: &String| s.len();
let composed = concat.and_then(length);
assert_eq!(
composed.apply(&String::from("hello"), &String::from("world")),
11
);
}
#[test]
fn test_fn_bi_function_once_ops_when_or_else() {
let add1 = |x: &i32, y: &i32| *x + *y;
let multiply1 = |x: &i32, y: &i32| *x * *y;
let conditional1 = add1
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(multiply1);
assert_eq!(conditional1.apply(&3, &4), 7);
let add2 = |x: &i32, y: &i32| *x + *y;
let multiply2 = |x: &i32, y: &i32| *x * *y;
let conditional2 = add2
.when(|x: &i32, y: &i32| *x <= 0 || *y <= 0)
.or_else(multiply2);
assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_fn_bi_function_once_ops_when_with_box_predicate() {
let add1 = |x: &i32, y: &i32| *x + *y;
let multiply1 = |x: &i32, y: &i32| *x * *y;
let both_positive = BoxBiPredicate::new(|x: &i32, y: &i32| *x > 0 && *y > 0);
let conditional1 = add1.when(both_positive).or_else(multiply1);
assert_eq!(conditional1.apply(&3, &4), 7);
let add2 = |x: &i32, y: &i32| *x + *y;
let multiply2 = |x: &i32, y: &i32| *x * *y;
let conditional2 = add2
.when(BoxBiPredicate::new(|x: &i32, y: &i32| *x <= 0 || *y <= 0))
.or_else(multiply2);
assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_fn_bi_function_once_ops_when_with_rc_predicate() {
let add1 = |x: &i32, y: &i32| *x + *y;
let multiply1 = |x: &i32, y: &i32| *x * *y;
let both_positive = RcBiPredicate::new(|x: &i32, y: &i32| *x > 0 && *y > 0);
let conditional1 = add1.when(both_positive.clone()).or_else(multiply1);
assert_eq!(conditional1.apply(&3, &4), 7);
let add2 = |x: &i32, y: &i32| *x + *y;
let multiply2 = |x: &i32, y: &i32| *x * *y;
let conditional2 = add2
.when(RcBiPredicate::new(|x: &i32, y: &i32| *x <= 0 || *y <= 0))
.or_else(multiply2);
assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_fn_bi_function_once_ops_when_with_arc_predicate() {
let add1 = |x: &i32, y: &i32| *x + *y;
let multiply1 = |x: &i32, y: &i32| *x * *y;
let both_positive = ArcBiPredicate::new(|x: &i32, y: &i32| *x > 0 && *y > 0);
let conditional1 = add1.when(both_positive.clone()).or_else(multiply1);
assert_eq!(conditional1.apply(&3, &4), 7);
let add2 = |x: &i32, y: &i32| *x + *y;
let multiply2 = |x: &i32, y: &i32| *x * *y;
let conditional2 = add2
.when(ArcBiPredicate::new(|x: &i32, y: &i32| *x <= 0 || *y <= 0))
.or_else(multiply2);
assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_closure_bi_function_once_into_box() {
let multiply = |x: &i32, y: &i32| *x * *y;
let boxed1 = multiply.into_box();
let boxed2 = (|x: &i32, y: &i32| *x * *y).into_box();
assert_eq!(boxed1.apply(&3, &4), 12);
assert_eq!(boxed2.apply(&5, &6), 30);
}
#[test]
fn test_closure_bi_function_once_into_fn() {
let add = |x: &i32, y: &i32| *x + *y;
let func1 = add.into_fn();
let func2 = (|x: &i32, y: &i32| *x + *y).into_fn();
assert_eq!(func1(&10, &20), 30);
assert_eq!(func2(&1, &2), 3);
}
#[test]
fn test_closure_bi_function_once_to_box() {
let subtract = |x: &i32, y: &i32| *x - *y;
let boxed1 = subtract.to_box();
let boxed2 = (|x: &i32, y: &i32| *x - *y).to_box();
assert_eq!(boxed1.apply(&10, &3), 7);
assert_eq!(boxed2.apply(&20, &5), 15);
let another_boxed = (|x: &i32, y: &i32| *x - *y).to_box();
assert_eq!(another_boxed.apply(&8, &2), 6);
}
#[test]
fn test_closure_bi_function_once_to_fn() {
let divide = |x: &i32, y: &i32| *x / *y;
let func1 = divide.to_fn();
let func2 = (|x: &i32, y: &i32| *x / *y).to_fn();
assert_eq!(func1(&20, &4), 5);
assert_eq!(func2(&15, &3), 5);
let another_func = (|x: &i32, y: &i32| *x / *y).to_fn();
assert_eq!(another_func(&30, &6), 5);
}
#[test]
fn test_closure_bi_function_once_and_then() {
let add = |x: &i32, y: &i32| *x + *y;
let double = |x: &i32| *x * 2;
let composed1 = add.and_then(double);
let composed2 = (|x: &i32, y: &i32| *x + *y).and_then(|x: &i32| *x * 2);
assert_eq!(composed1.apply(&3, &4), 14); assert_eq!(composed2.apply(&1, &2), 6); }
#[test]
fn test_closure_bi_function_once_when() {
let multiply1 = |x: &i32, y: &i32| *x * *y;
let add1 = |x: &i32, y: &i32| *x + *y;
let conditional1 = multiply1
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(add1);
assert_eq!(conditional1.apply(&3, &4), 12);
let multiply2 = |x: &i32, y: &i32| *x * *y;
let add2 = |x: &i32, y: &i32| *x + *y;
let conditional2 = multiply2
.when(|x: &i32, y: &i32| *x <= 0 || *y <= 0)
.or_else(add2);
assert_eq!(conditional2.apply(&-3, &4), -12);
let multiply3 = |x: &i32, y: &i32| *x * *y;
let add3 = |x: &i32, y: &i32| *x + *y;
let conditional3 = multiply3
.when(|x: &i32, y: &i32| *x > 0 && *y < 0)
.or_else(add3);
assert_eq!(conditional3.apply(&3, &-4), -12); }
#[test]
fn test_box_conditional_bi_function_once_when_or_else() {
let add1 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let multiply1 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x * *y);
let conditional1 = add1
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(multiply1);
let add2 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let multiply2 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x * *y);
let conditional2 = add2
.when(|x: &i32, y: &i32| *x <= 0 || *y <= 0)
.or_else(multiply2);
assert_eq!(conditional1.apply(&3, &4), 7); assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_box_conditional_bi_function_once_complex_conditions() {
let add1 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let subtract1 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x - *y);
let conditional1 = add1.when(|x: &i32, y: &i32| *x >= *y).or_else(subtract1);
let add2 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let subtract2 = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x - *y);
let conditional2 = add2.when(|x: &i32, y: &i32| *x < *y).or_else(subtract2);
assert_eq!(conditional1.apply(&5, &3), 8); assert_eq!(conditional2.apply(&3, &5), 8); }
#[test]
fn test_box_conditional_bi_function_once_with_string_operations() {
let concat1 = BoxBiFunctionOnce::new(|x: &String, y: &String| format!("{} {}", x, y));
let reverse_concat1 = BoxBiFunctionOnce::new(|x: &String, y: &String| format!("{} {}", y, x));
let conditional1 = concat1
.when(|x: &String, y: &String| x.len() >= y.len())
.or_else(reverse_concat1);
let concat2 = BoxBiFunctionOnce::new(|x: &String, y: &String| format!("{} {}", x, y));
let reverse_concat2 = BoxBiFunctionOnce::new(|x: &String, y: &String| format!("{} {}", y, x));
let conditional2 = concat2
.when(|x: &String, y: &String| x.len() < y.len())
.or_else(reverse_concat2);
assert_eq!(
conditional1.apply(&String::from("hello"), &String::from("hi")),
"hello hi"
); assert_eq!(
conditional2.apply(&String::from("hi"), &String::from("hello")),
"hi hello"
); }
#[test]
fn test_bi_function_once_complex_composition() {
let add = |x: &i32, y: &i32| *x + *y;
let multiply_by_two = |x: &i32| *x * 2;
let to_string = |x: &i32| x.to_string();
let composed = add.and_then(multiply_by_two).and_then(to_string);
assert_eq!(composed.apply(&3, &4), "14"); }
#[test]
fn test_bi_function_once_conditional_composition() {
let add = |x: &i32, y: &i32| *x + *y;
let multiply = |x: &i32, y: &i32| *x * *y;
let square = |x: &i32| *x * *x;
let conditional1 = add
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(multiply)
.and_then(square);
let conditional2 = add
.when(|x: &i32, y: &i32| *x <= 0 || *y <= 0)
.or_else(multiply)
.and_then(square);
assert_eq!(conditional1.apply(&3, &4), 49); assert_eq!(conditional2.apply(&-3, &4), 1); }
#[test]
fn test_bi_function_once_with_custom_types() {
#[derive(Debug, PartialEq)]
struct Point {
x: i32,
y: i32,
}
let add_points = |p1: &Point, p2: &Point| Point {
x: p1.x + p2.x,
y: p1.y + p2.y,
};
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 3, y: 4 };
let result = add_points.apply(&p1, &p2);
assert_eq!(result, Point { x: 4, y: 6 });
}
#[test]
fn test_bi_function_once_with_result_types() {
let safe_divide = |x: &i32, y: &i32| {
if *y == 0 {
Err("Division by zero")
} else {
Ok(*x / *y)
}
};
let to_string = |result: &Result<i32, &str>| match result {
Ok(value) => format!("Result: {}", value),
Err(msg) => format!("Error: {}", msg),
};
let composed1 = safe_divide.and_then(to_string);
let composed2 = (|x: &i32, y: &i32| {
if *y == 0 {
Err("Division by zero")
} else {
Ok(*x / *y)
}
})
.and_then(to_string);
assert_eq!(composed1.apply(&10, &2), "Result: 5");
assert_eq!(composed2.apply(&10, &0), "Error: Division by zero");
}
#[test]
fn test_bi_function_once_with_option_types() {
let add_options = |x: &Option<i32>, y: &Option<i32>| match (x, y) {
(Some(a), Some(b)) => Some(a + b),
_ => None,
};
let format_option = |opt: &Option<i32>| match opt {
Some(value) => format!("Value: {}", value),
None => "No value".to_string(),
};
let composed1 = add_options.and_then(format_option);
let composed2 = (|x: &Option<i32>, y: &Option<i32>| match (x, y) {
(Some(a), Some(b)) => Some(a + b),
_ => None,
})
.and_then(|opt: &Option<i32>| match opt {
Some(value) => format!("Value: {}", value),
None => "No value".to_string(),
});
assert_eq!(composed1.apply(&Some(3), &Some(4)), "Value: 7");
assert_eq!(composed2.apply(&Some(3), &None), "No value");
}
#[test]
fn test_box_bi_function_once_display_without_name() {
let func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let display = format!("{}", func);
assert!(display.contains("BoxBiFunctionOnce"));
}
#[test]
fn test_box_bi_function_once_display_with_name() {
let func = BoxBiFunctionOnce::new_with_name("adder", |x: &i32, y: &i32| *x + *y);
let display = format!("{}", func);
assert!(display.contains("adder"));
assert!(display.contains("BoxBiFunctionOnce"));
}
#[test]
fn test_box_bi_function_once_debug() {
let func = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let debug = format!("{:?}", func);
assert!(debug.contains("BoxBiFunctionOnce"));
}
#[test]
fn test_box_conditional_bi_function_once_display() {
let add = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let conditional = add.when(|x: &i32, _y: &i32| *x > 0);
let display = format!("{}", conditional);
assert!(display.contains("BoxConditionalBiFunctionOnce"));
}
#[test]
fn test_box_conditional_bi_function_once_debug() {
let add = BoxBiFunctionOnce::new(|x: &i32, y: &i32| *x + *y);
let conditional = add.when(|x: &i32, _y: &i32| *x > 0);
let debug = format!("{:?}", conditional);
assert!(debug.contains("BoxConditionalBiFunctionOnce"));
}
#[test]
fn test_bi_function_once_with_error_propagation() {
#[derive(Debug, PartialEq, Clone)]
enum MathError {
DivisionByZero,
Overflow,
}
let safe_divide = |x: &i32, y: &i32| -> Result<i32, MathError> {
if *y == 0 {
Err(MathError::DivisionByZero)
} else if *x == i32::MIN && *y == -1 {
Err(MathError::Overflow)
} else {
Ok(*x / *y)
}
};
let multiply_by_two = |result: &Result<i32, MathError>| result.clone().map(|x| x * 2);
let composed1 = safe_divide.and_then(multiply_by_two);
let safe_divide2 = |x: &i32, y: &i32| -> Result<i32, MathError> {
if *y == 0 {
Err(MathError::DivisionByZero)
} else if *x == i32::MIN && *y == -1 {
Err(MathError::Overflow)
} else {
Ok(*x / *y)
}
};
let composed2 = safe_divide2.and_then(multiply_by_two);
assert_eq!(composed1.apply(&10, &2), Ok(10)); assert_eq!(composed2.apply(&10, &0), Err(MathError::DivisionByZero));
}
#[test]
fn test_custom_bi_function_once_default_methods() {
#[derive(Debug)]
struct CustomBiFunctionOnce {
multiplier: i32,
}
impl BiFunctionOnce<i32, i32, i32> for CustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier
}
}
let custom_func = CustomBiFunctionOnce { multiplier: 3 };
let boxed = custom_func.into_box();
assert_eq!(boxed.apply(&2, &4), 24);
}
#[test]
fn test_custom_bi_function_once_into_fn() {
#[derive(Debug)]
struct CustomBiFunctionOnce {
multiplier: i32,
}
impl BiFunctionOnce<i32, i32, i32> for CustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier
}
}
let custom_func = CustomBiFunctionOnce { multiplier: 5 };
let func = custom_func.into_fn();
assert_eq!(func(&3, &4), 60); }
#[test]
fn test_cloneable_custom_bi_function_once_to_box() {
#[derive(Clone, Debug)]
struct CloneableCustomBiFunctionOnce {
multiplier: i32,
}
impl BiFunctionOnce<i32, i32, i32> for CloneableCustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier
}
}
let custom_func = CloneableCustomBiFunctionOnce { multiplier: 2 };
let boxed = custom_func.to_box();
assert_eq!(boxed.apply(&3, &5), 30);
let another_boxed = custom_func.to_box();
assert_eq!(another_boxed.apply(&2, &3), 12); }
#[test]
fn test_cloneable_custom_bi_function_once_to_fn() {
#[derive(Clone, Debug)]
struct CloneableCustomBiFunctionOnce {
multiplier: i32,
}
impl BiFunctionOnce<i32, i32, i32> for CloneableCustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier
}
}
let custom_func = CloneableCustomBiFunctionOnce { multiplier: 4 };
let func = custom_func.to_fn();
assert_eq!(func(&2, &6), 48);
let another_func = custom_func.to_fn();
assert_eq!(another_func(&1, &5), 20); }
#[test]
fn test_cloneable_bi_function_once_default_methods() {
#[derive(Clone, Debug)]
struct CloneableBiFunctionOnce {
multiplier: i32,
}
impl BiFunctionOnce<i32, i32, i32> for CloneableBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier
}
}
let custom_func = CloneableBiFunctionOnce { multiplier: 2 };
let boxed = custom_func.to_box();
assert_eq!(boxed.apply(&3, &5), 30);
let func = custom_func.to_fn();
assert_eq!(func(&3, &5), 30);
}
#[test]
fn test_bi_function_once_trait_blanket_impl_to_box_to_fn() {
let add = |x: &i32, y: &i32| *x + *y;
let boxed = add.to_box();
assert_eq!(boxed.apply(&7, &8), 15);
let func = add.to_fn();
assert_eq!(func(&7, &8), 15);
}
#[test]
fn test_bi_function_once_with_large_data() {
let large_vec = vec![1; 10000];
let combine = |v1: &Vec<i32>, v2: &Vec<i32>| {
let mut result = v1.clone();
result.extend(v2);
result
};
let func = BoxBiFunctionOnce::new(combine);
let result = func.apply(&large_vec, &large_vec);
assert_eq!(result.len(), 20000);
}
#[test]
fn test_bi_function_once_consumption_semantics() {
let counter = std::rc::Rc::new(std::cell::RefCell::new(0));
let increment_counter = {
let counter = counter.clone();
move |x: &i32, y: &i32| {
*counter.borrow_mut() += 1;
*x + *y
}
};
let func = BoxBiFunctionOnce::new(increment_counter);
assert_eq!(*counter.borrow(), 0);
assert_eq!(func.apply(&1, &2), 3);
assert_eq!(*counter.borrow(), 1);
}
#[test]
fn test_bi_function_once_with_references() {
let data = vec![1, 2, 3, 4, 5];
let func = |slice: &[i32], index: &usize| slice.get(*index).copied().unwrap_or(0);
assert_eq!(func(&data, &2), 3);
assert_eq!(func(&data, &10), 0); }
#[test]
fn test_custom_my_bi_function_once_comprehensive() {
#[derive(Debug)]
struct MyCustomBiFunctionOnce {
operation: String,
factor: i32,
}
impl MyCustomBiFunctionOnce {
fn new(operation: &str, factor: i32) -> Self {
Self {
operation: operation.to_string(),
factor,
}
}
}
impl BiFunctionOnce<i32, i32, String> for MyCustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> String {
let result = match self.operation.as_str() {
"add" => first + second,
"multiply" => first * second,
"subtract" => first - second,
_ => 0,
} * self.factor;
format!("{}({}, {}) = {}", self.operation, first, second, result)
}
}
let custom_func = MyCustomBiFunctionOnce::new("add", 2);
let result = custom_func.apply(&3, &4);
assert_eq!(result, "add(3, 4) = 14");
let custom_func2 = MyCustomBiFunctionOnce::new("multiply", 3);
let boxed = custom_func2.into_box();
let result2 = boxed.apply(&5, &6);
assert_eq!(result2, "multiply(5, 6) = 90");
let custom_func3 = MyCustomBiFunctionOnce::new("subtract", 4);
let func = custom_func3.into_fn();
let result3 = func(&10, &3);
assert_eq!(result3, "subtract(10, 3) = 28"); }
#[test]
fn test_custom_cloneable_my_bi_function_once_comprehensive() {
#[derive(Clone, Debug)]
struct MyCloneableCustomBiFunctionOnce {
base_value: i32,
multiplier: i32,
}
impl MyCloneableCustomBiFunctionOnce {
fn new(base_value: i32, multiplier: i32) -> Self {
Self {
base_value,
multiplier,
}
}
}
impl BiFunctionOnce<i32, i32, i32> for MyCloneableCustomBiFunctionOnce {
fn apply(self, first: &i32, second: &i32) -> i32 {
(first + second + self.base_value) * self.multiplier
}
}
let custom_func = MyCloneableCustomBiFunctionOnce::new(10, 2);
let result = custom_func.apply(&3, &4);
assert_eq!(result, 34);
let custom_func2 = MyCloneableCustomBiFunctionOnce::new(5, 3);
let boxed = custom_func2.to_box();
let result2 = boxed.apply(&2, &3);
assert_eq!(result2, 30);
let custom_func3 = MyCloneableCustomBiFunctionOnce::new(1, 4);
let boxed2 = custom_func3.to_box();
let result3 = boxed2.apply(&1, &1);
assert_eq!(result3, 12);
let custom_func4 = MyCloneableCustomBiFunctionOnce::new(2, 5);
let func = custom_func4.to_fn();
let result4 = func(&4, &5);
assert_eq!(result4, 55);
let custom_func5 = MyCloneableCustomBiFunctionOnce::new(0, 6);
let func2 = custom_func5.to_fn();
let result5 = func2(&2, &2);
assert_eq!(result5, 24); }
#[test]
fn test_custom_my_bi_function_once_all_default_methods() {
#[derive(Clone, Debug)]
struct ComprehensiveBiFunctionOnce {
prefix: String,
suffix: String,
scale: f64,
}
impl ComprehensiveBiFunctionOnce {
fn new(prefix: &str, suffix: &str, scale: f64) -> Self {
Self {
prefix: prefix.to_string(),
suffix: suffix.to_string(),
scale,
}
}
}
impl BiFunctionOnce<f64, f64, String> for ComprehensiveBiFunctionOnce {
fn apply(self, first: &f64, second: &f64) -> String {
let result = (first + second) * self.scale;
format!("{}{:.2}{}", self.prefix, result, self.suffix)
}
}
let func = ComprehensiveBiFunctionOnce::new("[", "]", 1.5);
let direct_result = func.apply(&3.5, &2.5);
assert_eq!(direct_result, "[9.00]");
let func2 = ComprehensiveBiFunctionOnce::new("<<", ">>", 2.0);
let boxed = func2.into_box();
let boxed_result = boxed.apply(&1.5, &2.5);
assert_eq!(boxed_result, "<<8.00>>");
let func3 = ComprehensiveBiFunctionOnce::new("(", ")", 0.5);
let closure = func3.into_fn();
let closure_result = closure(&4.0, &6.0);
assert_eq!(closure_result, "(5.00)");
let func4 = ComprehensiveBiFunctionOnce::new("{", "}", 3.0);
let boxed2 = func4.to_box();
let boxed_result2 = boxed2.apply(&2.0, &1.0);
assert_eq!(boxed_result2, "{9.00}");
let func5 = ComprehensiveBiFunctionOnce::new("<", ">", 4.0);
let closure2 = func5.to_fn();
let closure_result2 = closure2(&1.5, &1.5);
assert_eq!(closure_result2, "<12.00>");
let func6 = ComprehensiveBiFunctionOnce::new("*", "*", 1.0);
let _boxed3 = func6.to_box(); let _closure3 = func6.to_fn(); }
#[test]
fn test_custom_cloneable_bi_function_once_to_box() {
#[derive(Clone, Debug)]
struct MyCloneableBiFunction {
multiplier: i32,
offset: i32,
}
impl MyCloneableBiFunction {
fn new(multiplier: i32, offset: i32) -> Self {
Self { multiplier, offset }
}
}
impl BiFunctionOnce<i32, i32, i32> for MyCloneableBiFunction {
fn apply(self, first: &i32, second: &i32) -> i32 {
first * second * self.multiplier + self.offset
}
}
let func = MyCloneableBiFunction::new(3, 10);
let boxed = func.to_box();
assert_eq!(boxed.apply(&2, &4), 34);
let another_boxed = func.to_box();
assert_eq!(another_boxed.apply(&1, &5), 25);
let func_closure = func.to_fn();
assert_eq!(func_closure(&3, &2), 28);
let final_boxed = func.to_box();
assert_eq!(final_boxed.apply(&0, &10), 10); }