BoxBiConsumerOnce

Struct BoxBiConsumerOnce 

Source
pub struct BoxBiConsumerOnce<T, U> { /* private fields */ }
Expand description

BoxBiConsumerOnce struct

A one-time bi-consumer implementation based on Box<dyn FnOnce(&T, &U)> for single ownership scenarios. This is the simplest one-time bi-consumer type for truly one-time use.

§Features

  • Single Ownership: Not cloneable, ownership moves on use
  • Zero Overhead: No reference counting or locking
  • One-Time Use: Consumes self on first call
  • Builder Pattern: Method chaining consumes self naturally

§Use Cases

Choose BoxBiConsumerOnce when:

  • The bi-consumer is truly used only once
  • Building pipelines where ownership naturally flows
  • The consumer captures values that should be consumed
  • Performance is critical and sharing overhead is unacceptable

§Performance

BoxBiConsumerOnce has the best performance:

  • No reference counting overhead
  • No lock acquisition or runtime borrow checking
  • Direct function call through vtable
  • Minimal memory footprint (single pointer)

§Examples

use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};

let consumer = BoxBiConsumerOnce::new(|x: &i32, y: &i32| {
    println!("Sum: {}", x + y);
});
consumer.accept_once(&5, &3);

§Author

Haixing Hu

Implementations§

Source§

impl<T, U> BoxBiConsumerOnce<T, U>
where T: 'static, U: 'static,

Source

pub fn new<F>(f: F) -> Self
where F: FnOnce(&T, &U) + 'static,

Creates a new BoxBiConsumerOnce

§Type Parameters
  • F - The closure type
§Parameters
  • f - The closure to wrap
§Returns

Returns a new BoxBiConsumerOnce<T, U> instance

§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x * 2 + *y);
});
consumer.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![13]);
Examples found in repository?
examples/bi_consumer_once_demo.rs (lines 25-28)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}
Source

pub fn new_with_name<F>(name: &str, f: F) -> Self
where F: FnOnce(&T, &U) + 'static,

Creates a new BoxBiConsumerOnce with a name

§Type Parameters
  • F - The closure type
§Parameters
  • name - The name of the consumer
  • f - The closure to wrap
§Returns

Returns a new BoxBiConsumerOnce<T, U> instance with the specified name

§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new_with_name("sum_logger", move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
});
assert_eq!(consumer.name(), Some("sum_logger"));
consumer.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);
Source

pub fn name(&self) -> Option<&str>

Gets the name of the consumer

Examples found in repository?
examples/bi_consumer_once_demo.rs (line 134)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}
Source

pub fn set_name(&mut self, name: impl Into<String>)

Sets the name of the consumer

Examples found in repository?
examples/bi_consumer_once_demo.rs (line 136)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}
Source

pub fn noop() -> Self

Creates a no-op bi-consumer

§Returns

Returns a no-op bi-consumer

§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};

let noop = BoxBiConsumerOnce::<i32, i32>::noop();
noop.accept_once(&42, &10);
// Values unchanged
Examples found in repository?
examples/bi_consumer_once_demo.rs (line 133)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}
Source

pub fn and_then<C>(self, next: C) -> Self
where C: BiConsumerOnce<T, U> + 'static,

Chains another one-time bi-consumer in sequence

Returns a new consumer executing the current operation first, then the next operation. Consumes self.

§Type Parameters
  • C - The type of the next consumer
§Parameters
  • next - The consumer to execute after the current operation. Note: This parameter is passed by value and will transfer ownership. Since BoxBiConsumerOnce cannot be cloned, the parameter will be consumed. Can be:
    • A closure: |x: &T, y: &U|
    • A BoxBiConsumerOnce<T, U>
    • Any type implementing BiConsumerOnce<T, U>
§Returns

Returns a new composed BoxBiConsumerOnce<T, U>

§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};

let log = Arc::new(Mutex::new(Vec::new()));
let l1 = log.clone();
let l2 = log.clone();
let first = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
    l1.lock().unwrap().push(*x + *y);
});
let second = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
    l2.lock().unwrap().push(*x * *y);
});

// Both first and second are moved and consumed
let chained = first.and_then(second);
chained.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8, 15]);
// first.accept(&2, &3); // Would not compile - moved
// second.accept(&2, &3); // Would not compile - moved
Examples found in repository?
examples/bi_consumer_once_demo.rs (lines 41-44)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}
Source

pub fn when<P>(self, predicate: P) -> BoxConditionalBiConsumerOnce<T, U>
where P: BiPredicate<T, U> + 'static,

Creates a conditional bi-consumer

Returns a bi-consumer that only executes when a predicate is satisfied.

§Type Parameters
  • P - The predicate type
§Parameters
  • predicate - The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original bi-predicate, clone it first (if it implements Clone). Can be:
    • A closure: |x: &T, y: &U| -> bool
    • A function pointer: fn(&T, &U) -> bool
    • A BoxBiPredicate<T, U>
    • Any type implementing BiPredicate<T, U>
§Returns

Returns BoxConditionalBiConsumerOnce<T, U>

§Examples
use prism3_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
});
let conditional = consumer.when(|x: &i32, y: &i32| *x > 0 && *y > 0);

conditional.accept_once(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);
Examples found in repository?
examples/bi_consumer_once_demo.rs (line 55)
18fn main() {
19    println!("=== BiConsumerOnce Demo ===\n");
20
21    // 1. Basic usage
22    println!("1. Basic usage:");
23    let log = Arc::new(Mutex::new(Vec::new()));
24    let l = log.clone();
25    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
26        l.lock().unwrap().push(*x + *y);
27        println!("  Sum: {}", x + y);
28    });
29    consumer.accept_once(&10, &5);
30    println!("  Log: {:?}\n", *log.lock().unwrap());
31
32    // 2. Method chaining
33    println!("2. Method chaining:");
34    let log = Arc::new(Mutex::new(Vec::new()));
35    let l1 = log.clone();
36    let l2 = log.clone();
37    let chained = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
38        l1.lock().unwrap().push(*x + *y);
39        println!("  First: sum={}", x + y);
40    })
41    .and_then(move |x: &i32, y: &i32| {
42        l2.lock().unwrap().push(*x * *y);
43        println!("  Second: product={}", x * y);
44    });
45    chained.accept_once(&5, &3);
46    println!("  Log: {:?}\n", *log.lock().unwrap());
47
48    // 3. Conditional execution - true case
49    println!("3. Conditional execution - true case:");
50    let log = Arc::new(Mutex::new(Vec::new()));
51    let l = log.clone();
52    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
53        l.lock().unwrap().push(*x + *y);
54    })
55    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
56    conditional.accept_once(&5, &3);
57    println!("  Positive values: {:?}\n", *log.lock().unwrap());
58
59    // 4. Conditional execution - false case
60    println!("4. Conditional execution - false case:");
61    let log = Arc::new(Mutex::new(Vec::new()));
62    let l = log.clone();
63    let conditional = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
64        l.lock().unwrap().push(*x + *y);
65    })
66    .when(|x: &i32, y: &i32| *x > 0 && *y > 0);
67    conditional.accept_once(&-5, &3);
68    println!("  Negative value (unchanged): {:?}\n", *log.lock().unwrap());
69
70    // 5. Conditional branching
71    println!("5. Conditional branching:");
72    let log = Arc::new(Mutex::new(Vec::new()));
73    let l1 = log.clone();
74    let l2 = log.clone();
75    let branch = BoxBiConsumerOnce::new(move |x: &i32, _y: &i32| {
76        l1.lock().unwrap().push(*x);
77    })
78    .when(|x: &i32, y: &i32| *x > *y)
79    .or_else(move |_x: &i32, y: &i32| {
80        l2.lock().unwrap().push(*y);
81    });
82    branch.accept_once(&15, &10);
83    println!("  When x > y: {:?}\n", *log.lock().unwrap());
84
85    // 6. Working with closures directly
86    println!("6. Working with closures directly:");
87    let log = Arc::new(Mutex::new(Vec::new()));
88    let l = log.clone();
89    let closure = move |x: &i32, y: &i32| {
90        l.lock().unwrap().push(*x + *y);
91        println!("  Processed: {}", x + y);
92    };
93    closure.accept_once(&10, &20);
94    println!("  Log: {:?}\n", *log.lock().unwrap());
95
96    // 7. Moving captured values
97    println!("7. Moving captured values:");
98    let data = vec![1, 2, 3, 4, 5];
99    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
100        println!("  x={}, y={}", x, y);
101        println!("  Captured data: {:?}", data);
102        println!("  Data sum: {}", data.iter().sum::<i32>());
103    });
104    consumer.accept_once(&5, &3);
105    // data is no longer available here
106    println!();
107
108    // 8. Initialization callback
109    println!("8. Initialization callback:");
110    let log = Arc::new(Mutex::new(Vec::new()));
111    let l = log.clone();
112    let init_callback = BoxBiConsumerOnce::new(move |width: &i32, height: &i32| {
113        println!("  Initializing with dimensions: {}x{}", width, height);
114        l.lock().unwrap().push(*width * *height);
115    });
116    init_callback.accept_once(&800, &600);
117    println!("  Areas: {:?}\n", *log.lock().unwrap());
118
119    // 9. Cleanup callback
120    println!("9. Cleanup callback:");
121    let cleanup = BoxBiConsumerOnce::new(|count: &i32, total: &i32| {
122        println!("  Cleanup: processed {} out of {} items", count, total);
123        println!(
124            "  Success rate: {:.1}%",
125            (*count as f64 / *total as f64) * 100.0
126        );
127    });
128    cleanup.accept_once(&85, &100);
129    println!();
130
131    // 10. Name support
132    println!("10. Name support:");
133    let mut named_consumer = BoxBiConsumerOnce::<i32, i32>::noop();
134    println!("  Initial name: {:?}", named_consumer.name());
135
136    named_consumer.set_name("init_callback");
137    println!("  After setting name: {:?}", named_consumer.name());
138    println!("  Display: {}", named_consumer);
139    named_consumer.accept_once(&1, &2);
140    println!();
141
142    // 11. Print helpers
143    println!("11. Print helpers:");
144    let print = BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("{}, {}", x, y));
145    print.accept_once(&42, &10);
146
147    let print_with =
148        BoxBiConsumerOnce::new(|x: &i32, y: &i32| println!("Dimensions: {}, {}", x, y));
149    print_with.accept_once(&800, &600);
150    println!();
151
152    // 12. Converting to function
153    println!("12. Converting to function:");
154    let log = Arc::new(Mutex::new(Vec::new()));
155    let l = log.clone();
156    let consumer = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
157        l.lock().unwrap().push(*x + *y);
158    });
159    let func = consumer.into_fn_once();
160    func(&7, &3);
161    println!("  Log: {:?}\n", *log.lock().unwrap());
162
163    println!("=== Demo Complete ===");
164}

Trait Implementations§

Source§

impl<T, U> BiConsumerOnce<T, U> for BoxBiConsumerOnce<T, U>

Source§

fn accept_once(self, first: &T, second: &U)

Performs the one-time consumption operation Read more
Source§

fn into_box_once(self) -> BoxBiConsumerOnce<T, U>
where T: 'static, U: 'static,

Converts to BoxBiConsumerOnce Read more
Source§

fn into_fn_once(self) -> impl FnOnce(&T, &U)
where T: 'static, U: 'static,

Converts to a closure Read more
Source§

impl<T, U> Debug for BoxBiConsumerOnce<T, U>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, U> Display for BoxBiConsumerOnce<T, U>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T, U> Freeze for BoxBiConsumerOnce<T, U>

§

impl<T, U> !RefUnwindSafe for BoxBiConsumerOnce<T, U>

§

impl<T, U> !Send for BoxBiConsumerOnce<T, U>

§

impl<T, U> !Sync for BoxBiConsumerOnce<T, U>

§

impl<T, U> Unpin for BoxBiConsumerOnce<T, U>

§

impl<T, U> !UnwindSafe for BoxBiConsumerOnce<T, U>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.