Skip to main content

BiConsumerOnce

Trait BiConsumerOnce 

Source
pub trait BiConsumerOnce<T, U> {
    // Required method
    fn accept(self, first: &T, second: &U);

    // Provided methods
    fn into_box(self) -> BoxBiConsumerOnce<T, U>
       where Self: Sized + 'static { ... }
    fn into_fn(self) -> impl FnOnce(&T, &U)
       where Self: Sized + 'static { ... }
    fn to_box(&self) -> BoxBiConsumerOnce<T, U>
       where Self: Sized + Clone + 'static { ... }
    fn to_fn(&self) -> impl FnOnce(&T, &U)
       where Self: Sized + Clone + 'static { ... }
}
Expand description

BiConsumerOnce trait - Unified one-time bi-consumer interface

It is similar to the FnOnce(&T, &U) trait in the standard library.

Defines core behavior for all one-time bi-consumer types. Similar to a bi-consumer implementing FnOnce(&T, &U), performs operations accepting two value references but returning no result (side effects only), consuming itself in the process.

§Automatic Implementations

  • All closures implementing FnOnce(&T, &U)
  • BoxBiConsumerOnce<T, U>

§Features

  • Unified Interface: All bi-consumer types share the same accept method signature
  • Automatic Implementation: Closures automatically implement this trait with zero overhead
  • Type Conversions: Can convert to BoxBiConsumerOnce
  • Generic Programming: Write functions accepting any one-time bi-consumer type

§Examples

use qubit_function::{BiConsumerOnce, BoxBiConsumerOnce};
use std::sync::{Arc, Mutex};

fn apply_consumer<C: BiConsumerOnce<i32, i32>>(
    consumer: C,
    a: &i32,
    b: &i32
) {
    consumer.accept(a, b);
}

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let box_con = BoxBiConsumerOnce::new(move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
});
apply_consumer(box_con, &5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);

Required Methods§

Source

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

Performs the one-time consumption operation

Executes an operation on the given two references. The operation typically reads input values or produces side effects, but does not modify the input values themselves. Consumes self.

§Parameters
  • first - Reference to the first value to consume
  • second - Reference to the second value to consume
§Examples
use qubit_function::{BiConsumerOnce, BoxBiConsumerOnce};

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

Provided Methods§

Source

fn into_box(self) -> BoxBiConsumerOnce<T, U>
where Self: Sized + 'static,

Converts to BoxBiConsumerOnce

⚠️ Consumes self: Original consumer becomes unavailable after calling this method.

§Returns

Returns the wrapped BoxBiConsumerOnce<T, U>

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

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
};
let box_consumer = closure.into_box();
box_consumer.accept(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);
Source

fn into_fn(self) -> impl FnOnce(&T, &U)
where Self: Sized + 'static,

Converts to a closure

⚠️ Consumes self: Original consumer becomes unavailable after calling this method.

Converts the one-time bi-consumer to a closure usable with standard library methods requiring FnOnce.

§Returns

Returns a closure implementing FnOnce(&T, &U)

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

fn to_box(&self) -> BoxBiConsumerOnce<T, U>
where Self: Sized + Clone + 'static,

Convert to BoxBiConsumerOnce without consuming self

⚠️ Requires Clone: This method requires Self to implement Clone. Clones the current bi-consumer and then converts the clone to a BoxBiConsumerOnce.

§Returns

Returns the wrapped BoxBiConsumerOnce<T, U>

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

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
};
let box_consumer = closure.to_box();
box_consumer.accept(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);
Source

fn to_fn(&self) -> impl FnOnce(&T, &U)
where Self: Sized + Clone + 'static,

Convert to closure without consuming self

⚠️ Requires Clone: This method requires Self to implement Clone. Clones the current bi-consumer and then converts the clone to a closure.

§Returns

Returns a closure implementing FnOnce(&T, &U)

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

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32, y: &i32| {
    l.lock().unwrap().push(*x + *y);
};
let func = closure.to_fn();
func(&5, &3);
assert_eq!(*log.lock().unwrap(), vec![8]);

Implementors§

Source§

impl<F, T, U> BiConsumerOnce<T, U> for F
where F: FnOnce(&T, &U),

Source§

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

Source§

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