pub trait FnStatefulTransformerOps<T, R>: FnMut(T) -> R + Sized {
// Provided methods
fn and_then<S, F>(self, after: F) -> BoxStatefulTransformer<T, S>
where Self: 'static,
S: 'static,
F: StatefulTransformer<R, S> + 'static,
T: 'static,
R: 'static { ... }
fn when<P>(self, predicate: P) -> BoxConditionalStatefulTransformer<T, R>
where Self: 'static,
P: Predicate<T> + 'static,
T: 'static,
R: 'static { ... }
}Expand description
Extension trait for closures implementing FnMut(T) -> R
Provides composition methods (and_then, compose, when) for
closures without requiring explicit wrapping in BoxStatefulTransformer,
RcStatefulTransformer, or ArcStatefulTransformer.
This trait is automatically implemented for all closures that
implement FnMut(T) -> R.
§Design Rationale
While closures automatically implement StatefulTransformer<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 BoxStatefulTransformer for maximum flexibility.
§Examples
§Chain composition with and_then
use qubit_function::{StatefulTransformer, FnStatefulTransformerOps, FnTransformerOps, Transformer};
let mut counter1 = 0;
let transformer1 = move |x: i32| {
counter1 += 1;
x + counter1
};
let mut counter2 = 0;
let transformer2 = move |x: i32| {
counter2 += 1;
x * counter2
};
let mut composed = FnStatefulTransformerOps::and_then(transformer1, transformer2);
assert_eq!(composed.apply(10), 11); // (10 + 1) * 1§Reverse composition with compose
use qubit_function::{StatefulTransformer, FnStatefulTransformerOps, FnTransformerOps, Transformer};
let transformer = |x: i32| x * 2;
let mut composed = transformer.compose(|x: i32| x + 1);
assert_eq!(composed.apply(10), 22); // (10 + 1) * 2§Conditional mapping with when
use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
let mut transformer = (|x: i32| x * 2)
.when(|x: &i32| *x > 0)
.or_else(|x: i32| -x);
assert_eq!(transformer.apply(5), 10);
assert_eq!(transformer.apply(-5), 5);§Author
Haixing Hu
Provided Methods§
Sourcefn and_then<S, F>(self, after: F) -> BoxStatefulTransformer<T, S>where
Self: 'static,
S: 'static,
F: StatefulTransformer<R, S> + 'static,
T: 'static,
R: 'static,
fn and_then<S, F>(self, after: F) -> BoxStatefulTransformer<T, S>where
Self: 'static,
S: 'static,
F: StatefulTransformer<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
BoxStatefulTransformer.
§Type Parameters
S- The output type of the after transformerF- The type of the after transformer (must implement StatefulTransformer<R, S>)
§Parameters
after- The transformer to apply after self. Can be:- A closure:
|x: R| -> S - A
BoxStatefulTransformer<R, S> - An
RcStatefulTransformer<R, S> - An
ArcStatefulTransformer<R, S> - Any type implementing
StatefulTransformer<R, S>
- A closure:
§Returns
A new BoxStatefulTransformer<T, S> representing the composition
§Examples
use qubit_function::{StatefulTransformer, FnStatefulTransformerOps, BoxStatefulTransformer};
let mut counter1 = 0;
let transformer1 = move |x: i32| {
counter1 += 1;
x + counter1
};
let mut counter2 = 0;
let transformer2 = BoxStatefulTransformer::new(move |x: i32| {
counter2 += 1;
x * counter2
});
let mut composed = transformer1.and_then(transformer2);
assert_eq!(composed.apply(10), 11);Examples found in repository?
23fn main() {
24 println!("=== StatefulTransformer Demo ===\n");
25
26 // 1. Basic BoxStatefulTransformer with state
27 println!("1. BoxStatefulTransformer with stateful counter:");
28 let mut counter = 0;
29 let mut mapper = BoxStatefulTransformer::new(move |x: i32| {
30 counter += 1;
31 format!("Item #{}: {}", counter, x)
32 });
33
34 println!(" {}", mapper.apply(100)); // Item #1: 100
35 println!(" {}", mapper.apply(200)); // Item #2: 200
36 println!(" {}", mapper.apply(300)); // Item #3: 300
37
38 // 2. Composing mappers with and_then
39 println!("\n2. Composing mappers with and_then:");
40 let mut counter1 = 0;
41 let mapper1 = BoxStatefulTransformer::new(move |x: i32| {
42 counter1 += 1;
43 x + counter1
44 });
45
46 let mut counter2 = 0;
47 let mapper2 = BoxStatefulTransformer::new(move |x: i32| {
48 counter2 += 1;
49 x * counter2
50 });
51
52 let mut composed = mapper1.and_then(mapper2);
53 println!(" First call: {}", composed.apply(10)); // (10 + 1) * 1 = 11
54 println!(" Second call: {}", composed.apply(10)); // (10 + 2) * 2 = 24
55 println!(" Third call: {}", composed.apply(10)); // (10 + 3) * 3 = 39
56
57 // 3. Conditional mapping with when/or_else
58 println!("\n3. Conditional mapping:");
59 let mut high_count = 0;
60 let mut low_count = 0;
61
62 let mut conditional = BoxStatefulTransformer::new(move |x: i32| {
63 high_count += 1;
64 format!("High[{}]: {} * 2 = {}", high_count, x, x * 2)
65 })
66 .when(|x: &i32| *x >= 10)
67 .or_else(move |x| {
68 low_count += 1;
69 format!("Low[{}]: {} + 1 = {}", low_count, x, x + 1)
70 });
71
72 println!(" {}", conditional.apply(15)); // High[1]: 15 * 2 = 30
73 println!(" {}", conditional.apply(5)); // Low[1]: 5 + 1 = 6
74 println!(" {}", conditional.apply(20)); // High[2]: 20 * 2 = 40
75
76 // 4. RcStatefulTransformer for cloneable mappers
77 println!("\n4. RcStatefulTransformer (cloneable, single-threaded):");
78 let mut counter = 0;
79 let mapper = RcStatefulTransformer::new(move |x: i32| {
80 counter += 1;
81 x + counter
82 });
83
84 let mut mapper1 = mapper.clone();
85 let mut mapper2 = mapper.clone();
86
87 println!(" mapper1: {}", mapper1.apply(10)); // 11
88 println!(" mapper2: {}", mapper2.apply(10)); // 12
89 println!(" mapper1: {}", mapper1.apply(10)); // 13
90
91 // 5. ArcStatefulTransformer for thread-safe mappers
92 println!("\n5. ArcStatefulTransformer (thread-safe):");
93 let mut counter = 0;
94 let mapper = ArcStatefulTransformer::new(move |x: i32| {
95 counter += 1;
96 format!("Result[{}]: {}", counter, x * 2)
97 });
98
99 let mut mapper_clone = mapper.clone();
100 println!(" Original: {}", mapper_clone.apply(5)); // Result[1]: 10
101 println!(" Clone: {}", mapper_clone.apply(7)); // Result[2]: 14
102
103 // 6. Using FnStatefulTransformerOps extension trait
104 println!("\n6. Using FnStatefulTransformerOps extension trait:");
105 let mut count = 0;
106 let mut mapper = (move |x: i32| {
107 count += 1;
108 x + count
109 })
110 .and_then(|x| x * 2);
111
112 println!(" {}", mapper.apply(10)); // (10 + 1) * 2 = 22
113 println!(" {}", mapper.apply(10)); // (10 + 2) * 2 = 24
114
115 // 7. Building a complex pipeline
116 println!("\n7. Complex processing pipeline:");
117 let mut step1_count = 0;
118 let step1 = BoxStatefulTransformer::new(move |x: i32| {
119 step1_count += 1;
120 format!("Step1[{}]: {}", step1_count, x)
121 });
122
123 let mut step2_count = 0;
124 let step2 = BoxStatefulTransformer::new(move |s: String| {
125 step2_count += 1;
126 format!("{} -> Step2[{}]", s, step2_count)
127 });
128
129 let mut step3_count = 0;
130 let step3 = BoxStatefulTransformer::new(move |s: String| {
131 step3_count += 1;
132 format!("{} -> Step3[{}]", s, step3_count)
133 });
134
135 let mut pipeline = step1.and_then(step2).and_then(step3);
136
137 println!(" {}", pipeline.apply(100));
138 println!(" {}", pipeline.apply(200));
139
140 // 7. TransformerOnce implementation - consuming transformers
141 println!("\n7. TransformerOnce implementation - consuming StatefulTransformers:");
142
143 // BoxStatefulTransformer can be consumed as TransformerOnce
144 let mut counter = 0;
145 let mut box_mapper = BoxStatefulTransformer::new(move |x: i32| {
146 counter += 1;
147 x * counter
148 });
149 println!(
150 " BoxStatefulTransformer consumed once: {}",
151 box_mapper.apply(10)
152 ); // 10 * 1 = 10
153
154 // RcStatefulTransformer can be consumed as TransformerOnce
155 let mut counter = 0;
156 let mut rc_mapper = RcStatefulTransformer::new(move |x: i32| {
157 counter += 1;
158 x + counter
159 });
160 let rc_clone = rc_mapper.clone(); // Clone before consuming
161 println!(
162 " RcStatefulTransformer consumed once: {}",
163 rc_mapper.apply(10)
164 ); // 10 + 1 = 11
165 println!(" RcStatefulTransformer clone still works: {}", {
166 let mut rc_clone_for_call = rc_clone.clone();
167 rc_clone_for_call.apply(10)
168 }); // 10 + 2 = 12
169
170 // ArcStatefulTransformer can be consumed as TransformerOnce
171 let mut counter = 0;
172 let mut arc_mapper = ArcStatefulTransformer::new(move |x: i32| {
173 counter += 1;
174 x * counter
175 });
176 let arc_clone = arc_mapper.clone(); // Clone before consuming
177 println!(
178 " ArcStatefulTransformer consumed once: {}",
179 arc_mapper.apply(10)
180 ); // 10 * 1 = 10
181 println!(" ArcStatefulTransformer clone still works: {}", {
182 let mut arc_clone_for_call = arc_clone.clone();
183 arc_clone_for_call.apply(10)
184 }); // 10 * 2 = 20
185
186 // 8. Converting to BoxTransformerOnce
187 println!("\n8. Converting StatefulTransformers to BoxTransformerOnce:");
188
189 let mut counter = 0;
190 let mapper = BoxStatefulTransformer::new(move |x: i32| {
191 counter += 1;
192 x * counter
193 });
194 let mut once_mapper = mapper.into_box();
195 println!(
196 " BoxStatefulTransformer->BoxTransformerOnce: {}",
197 once_mapper.apply(5)
198 ); // 5 * 1 = 5
199
200 // RcStatefulTransformer can use to_box() to preserve original
201 let mut counter = 0;
202 let rc_mapper = RcStatefulTransformer::new(move |x: i32| {
203 counter += 1;
204 x * counter
205 });
206 let mut once_mapper = rc_mapper.to_box();
207 println!(
208 " RcStatefulTransformer->BoxTransformerOnce: {}",
209 once_mapper.apply(5)
210 ); // 5 * 1 = 5
211 println!(" Original RcStatefulTransformer still works: {}", {
212 let mut rc_original_for_call = rc_mapper.clone();
213 rc_original_for_call.apply(5)
214 }); // 5 * 2 = 10
215
216 println!("\n=== Demo Complete ===");
217}Sourcefn when<P>(self, predicate: P) -> BoxConditionalStatefulTransformer<T, R>where
Self: 'static,
P: Predicate<T> + 'static,
T: 'static,
R: 'static,
fn when<P>(self, predicate: P) -> BoxConditionalStatefulTransformer<T, R>where
Self: 'static,
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. 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 BoxConditionalStatefulTransformer<T, R>
§Examples
use qubit_function::{StatefulTransformer, FnStatefulTransformerOps};
let mut transformer = (|x: i32| x * 2)
.when(|x: &i32| *x > 0)
.or_else(|x: i32| -x);
assert_eq!(transformer.apply(5), 10);
assert_eq!(transformer.apply(-5), 5);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> FnStatefulTransformerOps<T, R> for Fwhere
F: FnMut(T) -> R,
Blanket implementation of FnStatefulTransformerOps for all closures
Automatically implements FnStatefulTransformerOps<T, R> for any type that
implements FnMut(T) -> R.
§Author
Haixing Hu