pub trait FnMutatingFunctionOps<T, R>:
Fn(&mut T) -> R
+ Sized
+ 'static {
// Provided methods
fn and_then<S, F>(self, after: F) -> BoxMutatingFunction<T, S>
where S: 'static,
F: Function<R, S> + 'static,
T: 'static,
R: 'static { ... }
fn when<P>(self, predicate: P) -> BoxConditionalMutatingFunction<T, R>
where P: Predicate<T> + 'static,
T: 'static,
R: 'static { ... }
}Expand description
Extension trait for closures implementing the base function trait
Provides composition methods (and_then, when) for closures
and function pointers without requiring explicit wrapping.
This trait is automatically implemented for all closures and function pointers that implement the base function trait.
§Design Rationale
While closures automatically implement the base function trait through blanket
implementation, they don’t have access to instance methods like and_then,
and when. This extension trait provides those methods,
returning the appropriate Box-based function type for maximum flexibility.
§Examples
§Chain composition with and_then
use prism3_function::{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");§Conditional transformation with when
use prism3_function::{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);§Author
Haixing Hu
Provided Methods§
Sourcefn and_then<S, F>(self, after: F) -> BoxMutatingFunction<T, S>where
S: 'static,
F: Function<R, S> + 'static,
T: 'static,
R: 'static,
fn and_then<S, F>(self, after: F) -> BoxMutatingFunction<T, S>where
S: 'static,
F: Function<R, S> + 'static,
T: 'static,
R: 'static,
Chain composition - applies self first, then after
Creates a new function that applies this function first, then applies the after function to the result. Consumes self and returns a Box-based function.
§Type Parameters
S- The output type of the after functionF- The type of the after function (must implement the function trait)
§Parameters
after- The function to apply after self. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original function, clone it first (if it implementsClone). Can be:- A closure
- A function pointer
- A Box-based function
- An Rc-based function
- An Arc-based function
- Any type implementing the function trait
§Returns
A new Box-based function representing the composition
§Examples
§Direct value passing (ownership transfer)
use prism3_function::{Function, FnFunctionOps, BoxFunction};
let double = |x: i32| x * 2;
let to_string = BoxFunction::new(|x: i32| x.to_string());
// to_string is moved here
let composed = double.and_then(to_string);
assert_eq!(composed.apply(21), "42");
// to_string.apply(5); // Would not compile - moved§Preserving original with clone
use prism3_function::{Function, FnFunctionOps, BoxFunction};
let double = |x: i32| x * 2;
let to_string = BoxFunction::new(|x: i32| x.to_string());
// Clone to preserve original
let composed = double.and_then(to_string.clone());
assert_eq!(composed.apply(21), "42");
// Original still usable
assert_eq!(to_string.apply(5), "5");Sourcefn when<P>(self, predicate: P) -> BoxConditionalMutatingFunction<T, R>where
P: Predicate<T> + 'static,
T: 'static,
R: 'static,
fn when<P>(self, predicate: P) -> BoxConditionalMutatingFunction<T, R>where
P: Predicate<T> + 'static,
T: 'static,
R: 'static,
Creates a conditional function
Returns a function that only executes when a predicate is satisfied.
You must call or_else() to provide an alternative function for when
the condition is not satisfied.
§Parameters
predicate- The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
Returns the appropriate conditional function type
§Examples
§Basic usage with or_else
use prism3_function::{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);§Preserving predicate with clone
use prism3_function::{Function, FnFunctionOps, BoxPredicate};
let double = |x: i32| x * 2;
let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
// Clone to preserve original predicate
let conditional = double.when(is_positive.clone())
.or_else(|x: i32| -x);
assert_eq!(conditional.apply(5), 10);
// Original predicate still usable
assert!(is_positive.test(&3));Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.