ConsumerOnce

Trait ConsumerOnce 

Source
pub trait ConsumerOnce<T> {
    // Required method
    fn accept(self, value: &T);

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

ConsumerOnce trait - Unified one-time consumer interface

Defines the core behavior of all one-time consumer types. Similar to consumers implementing FnOnce(&T), executes operations that accept a value reference but return no result (only side effects), consuming itself in the process.

§Automatic Implementation

  • All closures implementing FnOnce(&T)
  • BoxConsumerOnce<T>

§Features

  • Unified Interface: All consumer types share the same accept method signature
  • Automatic Implementation: Closures automatically implement this trait with zero overhead
  • Type Conversion: Can be converted to BoxConsumerOnce
  • Generic Programming: Write functions that work with any one-time consumer type

§Examples

use prism3_function::{ConsumerOnce, BoxConsumerOnce};
use std::sync::{Arc, Mutex};

fn apply_consumer<C: ConsumerOnce<i32>>(consumer: C, value: &i32) {
    consumer.accept(value);
}

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

§Author

Hu Haixing

Required Methods§

Source

fn accept(self, value: &T)

Execute one-time consumption operation

Executes an operation on the given reference. The operation typically reads the input value or produces side effects, but does not modify the input value itself. Consumes self.

§Parameters
  • value - Reference to the value to be consumed
§Examples
use prism3_function::{ConsumerOnce, BoxConsumerOnce};

let consumer = BoxConsumerOnce::new(|x: &i32| println!("{}", x));
consumer.accept(&5);

Provided Methods§

Source

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

Convert to BoxConsumerOnce

⚠️ Consumes self: The original consumer will be unavailable after calling this method.

§Default Implementation

The default implementation wraps self in a BoxConsumerOnce by calling accept on the consumer. Types can override this method to provide more efficient conversions.

§Returns

Returns the wrapped BoxConsumerOnce<T>

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

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
    l.lock().unwrap().push(*x);
};
let box_consumer = closure.into_box();
box_consumer.accept(&5);
assert_eq!(*log.lock().unwrap(), vec![5]);
Examples found in repository?
examples/consumer_once_demo.rs (line 134)
16fn main() {
17    println!("=== ConsumerOnce Demo ===\n");
18
19    // 1. BoxConsumerOnce - Single ownership, one-time use
20    println!("1. BoxConsumerOnce - Single ownership");
21    {
22        let log = Arc::new(Mutex::new(Vec::new()));
23        let l = log.clone();
24        let consumer = BoxConsumerOnce::new(move |x: &i32| {
25            l.lock().unwrap().push(*x);
26            println!("  BoxConsumerOnce consumed: {}", x);
27        });
28        consumer.accept(&42);
29        println!("  Log: {:?}\n", *log.lock().unwrap());
30    }
31
32    // 2. BoxConsumerOnce - Method chaining
33    println!("2. BoxConsumerOnce - Method chaining");
34    {
35        let log = Arc::new(Mutex::new(Vec::new()));
36        let l1 = log.clone();
37        let l2 = log.clone();
38        let l3 = log.clone();
39        let chained = BoxConsumerOnce::new(move |x: &i32| {
40            l1.lock().unwrap().push(*x * 2);
41            println!("  Step 1: {} * 2 = {}", x, x * 2);
42        })
43        .and_then(move |x: &i32| {
44            l2.lock().unwrap().push(*x + 10);
45            println!("  Step 2: {} + 10 = {}", x, x + 10);
46        })
47        .and_then(move |x: &i32| {
48            l3.lock().unwrap().push(*x - 1);
49            println!("  Step 3: {} - 1 = {}", x, x - 1);
50        });
51        chained.accept(&5);
52        println!("  Log: {:?}\n", *log.lock().unwrap());
53    }
54
55    // 3. BoxConsumerOnce - Factory methods
56    println!("3. BoxConsumerOnce - Factory methods");
57    {
58        // No-op consumer
59        let noop = BoxConsumerOnce::<i32>::noop();
60        noop.accept(&42);
61        println!("  No-op consumer executed (no output)");
62
63        // Print consumer
64        print!("  Print consumer: ");
65        let print = BoxConsumerOnce::new(|x: &i32| println!("{}", x));
66        print.accept(&42);
67
68        // Print with prefix
69        print!("  Print with prefix: ");
70        let print_with = BoxConsumerOnce::new(|x: &i32| println!("Value: {}", x));
71        print_with.accept(&42);
72
73        // Conditional consumer
74        let log = Arc::new(Mutex::new(Vec::new()));
75        let l = log.clone();
76        let conditional = BoxConsumerOnce::new(move |x: &i32| {
77            l.lock().unwrap().push(*x * 2);
78        })
79        .when(|x: &i32| *x > 0);
80        conditional.accept(&5);
81        println!("  Conditional (positive): {:?}", *log.lock().unwrap());
82
83        let log = Arc::new(Mutex::new(Vec::new()));
84        let l = log.clone();
85        let conditional = BoxConsumerOnce::new(move |x: &i32| {
86            l.lock().unwrap().push(*x * 2);
87        })
88        .when(|x: &i32| *x > 0);
89        conditional.accept(&-5);
90        println!("  Conditional (negative): {:?}\n", *log.lock().unwrap());
91    }
92
93    // 4. Closure usage
94    println!("4. Closure usage");
95    {
96        let log = Arc::new(Mutex::new(Vec::new()));
97        let l = log.clone();
98        let closure = move |x: &i32| {
99            l.lock().unwrap().push(*x * 2);
100            println!("  Closure consumed: {}", x);
101        };
102        closure.accept(&42);
103        println!("  Log: {:?}\n", *log.lock().unwrap());
104    }
105
106    // 5. Closure chaining
107    println!("5. Closure chaining");
108    {
109        let log = Arc::new(Mutex::new(Vec::new()));
110        let l1 = log.clone();
111        let l2 = log.clone();
112        let chained = (move |x: &i32| {
113            l1.lock().unwrap().push(*x * 2);
114            println!("  Closure 1: {} * 2 = {}", x, x * 2);
115        })
116        .and_then(move |x: &i32| {
117            l2.lock().unwrap().push(*x + 10);
118            println!("  Closure 2: {} + 10 = {}", x, x + 10);
119        });
120        chained.accept(&5);
121        println!("  Log: {:?}\n", *log.lock().unwrap());
122    }
123
124    // 6. Type conversions
125    println!("6. Type conversions");
126    {
127        let log = Arc::new(Mutex::new(Vec::new()));
128
129        // Closure to BoxConsumerOnce
130        let l = log.clone();
131        let closure = move |x: &i32| {
132            l.lock().unwrap().push(*x);
133        };
134        let box_consumer = closure.into_box();
135        box_consumer.accept(&1);
136        println!("  BoxConsumerOnce: {:?}", *log.lock().unwrap());
137    }
138
139    // 7. Using with iterators (BoxConsumerOnce)
140    println!("7. Using with iterators");
141    {
142        let log = Arc::new(Mutex::new(Vec::new()));
143        let l = log.clone();
144        let consumer = BoxConsumerOnce::new(move |x: &i32| {
145            l.lock().unwrap().push(*x * 2);
146        });
147        // Note: This will panic because BoxConsumerOnce can only be called once
148        // vec![1, 2, 3, 4, 5].iter().for_each(consumer.into_fn());
149        consumer.accept(&1);
150        println!(
151            "  BoxConsumerOnce with single value: {:?}\n",
152            *log.lock().unwrap()
153        );
154    }
155
156    println!("=== Demo Complete ===");
157}
Source

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

Convert to closure

⚠️ Consumes self: The original consumer will be unavailable after calling this method.

Converts a one-time consumer to a closure that can be used directly in places where the standard library requires FnOnce.

§Default Implementation

The default implementation creates a closure that captures self and calls its accept method. Types can override this method to provide more efficient conversions.

§Returns

Returns a closure implementing FnOnce(&T)

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

let log = Arc::new(Mutex::new(Vec::new()));
let l = log.clone();
let closure = move |x: &i32| {
    l.lock().unwrap().push(*x * 2);
};
let func = closure.into_fn();
func(&5);
assert_eq!(*log.lock().unwrap(), vec![10]);
Source

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

Convert to BoxConsumerOnce without consuming self

⚠️ Requires Clone: This method requires Self to implement Clone. Clones the current consumer and wraps it in a BoxConsumerOnce.

§Default Implementation

The default implementation clones self and then calls into_box() on the clone. Types can override this method to provide more efficient conversions.

§Returns

Returns the wrapped BoxConsumerOnce<T>

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

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

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

Convert to closure without consuming self

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

§Default Implementation

The default implementation clones self and then calls into_fn() on the clone. Types can override this method to provide more efficient conversions.

§Returns

Returns a closure implementing FnOnce(&T)

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

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

Implementors§

Source§

impl<T> ConsumerOnce<T> for BoxConditionalConsumerOnce<T>
where T: 'static,

Source§

impl<T> ConsumerOnce<T> for BoxConsumerOnce<T>

Source§

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

Implement ConsumerOnce for all FnOnce(&T)