pub trait FnTransformerOps<T, R>:
Fn(T) -> R
+ Sized
+ 'static {
// Provided methods
fn and_then<S, F>(self, after: F) -> BoxTransformer<T, S>
where S: 'static,
F: Transformer<R, S> + 'static,
T: 'static,
R: 'static { ... }
fn compose<S, F>(self, before: F) -> BoxTransformer<S, R>
where S: 'static,
F: Transformer<S, T> + 'static,
T: 'static,
R: 'static { ... }
fn when<P>(self, predicate: P) -> BoxConditionalTransformer<T, R>
where P: Predicate<T> + 'static,
T: 'static,
R: 'static { ... }
}Expand description
Extension trait for closures implementing Fn(T) -> R
Provides composition methods (and_then, compose, when) for closures
and function pointers without requiring explicit wrapping in
BoxTransformer, RcTransformer, or ArcTransformer.
This trait is automatically implemented for all closures and function
pointers that implement Fn(T) -> R.
§Design Rationale
While closures automatically implement Transformer<T, R> through blanket
implementation, they don’t have access to instance methods like and_then,
compose, and when. This extension trait provides those methods,
returning BoxTransformer for maximum flexibility.
§Examples
§Chain composition with and_then
use prism3_function::{Transformer, FnTransformerOps};
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");§Reverse composition with compose
use prism3_function::{Transformer, FnTransformerOps};
let double = |x: i32| x * 2;
let add_one = |x: i32| x + 1;
let composed = double.compose(add_one);
assert_eq!(composed.apply(5), 12); // (5 + 1) * 2§Conditional transformation with when
use prism3_function::{Transformer, FnTransformerOps};
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) -> BoxTransformer<T, S>where
S: 'static,
F: Transformer<R, S> + 'static,
T: 'static,
R: 'static,
fn and_then<S, F>(self, after: F) -> BoxTransformer<T, S>where
S: 'static,
F: Transformer<R, S> + 'static,
T: 'static,
R: 'static,
Chain composition - applies self first, then after
Creates a new transformer that applies this transformer first, then
applies the after transformer to the result. Consumes self and returns
a BoxTransformer.
§Type Parameters
S- The output type of the after transformerF- The type of the after transformer (must implement Transformer<R, S>)
§Parameters
after- The transformer to apply after self. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original transformer, clone it first (if it implementsClone). Can be:- A closure:
|x: R| -> S - A function pointer:
fn(R) -> S - A
BoxTransformer<R, S> - An
RcTransformer<R, S> - An
ArcTransformer<R, S> - Any type implementing
Transformer<R, S>
- A closure:
§Returns
A new BoxTransformer<T, S> representing the composition
§Examples
§Direct value passing (ownership transfer)
use prism3_function::{Transformer, FnTransformerOps, BoxTransformer};
let double = |x: i32| x * 2;
let to_string = BoxTransformer::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::{Transformer, FnTransformerOps, BoxTransformer};
let double = |x: i32| x * 2;
let to_string = BoxTransformer::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 compose<S, F>(self, before: F) -> BoxTransformer<S, R>where
S: 'static,
F: Transformer<S, T> + 'static,
T: 'static,
R: 'static,
fn compose<S, F>(self, before: F) -> BoxTransformer<S, R>where
S: 'static,
F: Transformer<S, T> + 'static,
T: 'static,
R: 'static,
Reverse composition - applies before first, then self
Creates a new transformer that applies the before transformer first,
then applies this transformer to the result. Consumes self and returns
a BoxTransformer.
§Type Parameters
S- The input type of the before transformerF- The type of the before transformer (must implement Transformer<S, T>)
§Parameters
before- The transformer to apply before self. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original transformer, clone it first (if it implementsClone). Can be:- A closure:
|x: S| -> T - A function pointer:
fn(S) -> T - A
BoxTransformer<S, T> - An
RcTransformer<S, T> - An
ArcTransformer<S, T> - Any type implementing
Transformer<S, T>
- A closure:
§Returns
A new BoxTransformer<S, R> representing the composition
§Examples
§Direct value passing (ownership transfer)
use prism3_function::{Transformer, FnTransformerOps, BoxTransformer};
let double = |x: i32| x * 2;
let add_one = BoxTransformer::new(|x: i32| x + 1);
// add_one is moved here
let composed = double.compose(add_one);
assert_eq!(composed.apply(5), 12); // (5 + 1) * 2
// add_one.apply(3); // Would not compile - moved§Preserving original with clone
use prism3_function::{Transformer, FnTransformerOps, BoxTransformer};
let double = |x: i32| x * 2;
let add_one = BoxTransformer::new(|x: i32| x + 1);
// Clone to preserve original
let composed = double.compose(add_one.clone());
assert_eq!(composed.apply(5), 12); // (5 + 1) * 2
// Original still usable
assert_eq!(add_one.apply(3), 4);Sourcefn when<P>(self, predicate: P) -> BoxConditionalTransformer<T, R>where
P: Predicate<T> + 'static,
T: 'static,
R: 'static,
fn when<P>(self, predicate: P) -> BoxConditionalTransformer<T, R>where
P: Predicate<T> + 'static,
T: 'static,
R: 'static,
Creates a conditional transformer
Returns a transformer that only executes when a predicate is satisfied.
You must call or_else() to provide an alternative transformer 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 BoxConditionalTransformer<T, R>
§Examples
§Basic usage with or_else
use prism3_function::{Transformer, FnTransformerOps};
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::{Transformer, FnTransformerOps, 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.
Implementors§
impl<T, R, F> FnTransformerOps<T, R> for Fwhere
F: Fn(T) -> R + 'static,
Blanket implementation of FnTransformerOps for all closures
Automatically implements FnTransformerOps<T, R> for any type that
implements Fn(T) -> R.
§Author
Haixing Hu