Skip to main content

consumer_fn_usage/
consumer_fn_usage.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Demonstrates how into_fn and to_fn are used with function parameters that accept closures
10
11use qubit_function::{
12    ArcConsumer,
13    BoxConsumer,
14    Consumer,
15    RcConsumer,
16};
17use std::cell::RefCell;
18use std::rc::Rc;
19use std::sync::{
20    Arc,
21    Mutex,
22};
23
24fn main() {
25    println!("=== Consumer into_fn/to_fn Usage Examples ===\n");
26
27    // Example 1: Using BoxConsumer::into_fn to pass to standard library's map
28    println!("1. BoxConsumer::into_fn used with Iterator::for_each");
29    let log = Arc::new(Mutex::new(Vec::new()));
30    let l = log.clone();
31    let consumer = BoxConsumer::new(move |x: &i32| {
32        l.lock().unwrap().push(*x * 2);
33    });
34
35    // Convert consumer to closure and pass to for_each
36    [1, 2, 3, 4, 5].iter().for_each(consumer.into_fn());
37    println!("   Result: {:?}\n", *log.lock().unwrap());
38
39    // Example 2: Using ArcConsumer::to_fn can be used multiple times
40    println!("2. ArcConsumer::to_fn can be used multiple times");
41    let log2 = Arc::new(Mutex::new(Vec::new()));
42    let l2 = log2.clone();
43    let consumer2 = ArcConsumer::new(move |x: &i32| {
44        l2.lock().unwrap().push(*x + 10);
45    });
46
47    // to_fn doesn't consume consumer, can be called multiple times
48    [1, 2, 3].iter().for_each(consumer2.to_fn());
49    println!("   First time: {:?}", *log2.lock().unwrap());
50
51    [4, 5].iter().for_each(consumer2.to_fn());
52    println!("   Second time: {:?}\n", *log2.lock().unwrap());
53
54    // Example 3: Using RcConsumer::to_fn
55    println!("3. RcConsumer::to_fn used for single-threaded scenarios");
56    let log3 = Rc::new(RefCell::new(Vec::new()));
57    let l3 = log3.clone();
58    let consumer3 = RcConsumer::new(move |x: &i32| {
59        l3.borrow_mut().push(*x * 3);
60    });
61
62    [1, 2, 3, 4].iter().for_each(consumer3.to_fn());
63    println!("   Result: {:?}\n", *log3.borrow());
64
65    // Example 4: Using in custom functions
66    println!("4. Using in custom functions");
67    fn process_items<F>(items: Vec<i32>, consumer: F)
68    where
69        F: FnMut(&i32),
70    {
71        items.iter().for_each(consumer);
72    }
73
74    let log4 = Arc::new(Mutex::new(Vec::new()));
75    let l4 = log4.clone();
76    let consumer4 = BoxConsumer::new(move |x: &i32| {
77        l4.lock().unwrap().push(*x * 5);
78    });
79
80    // Use into_fn to convert Consumer to closure and pass to function
81    process_items(vec![1, 2, 3], consumer4.into_fn());
82    println!("   Result: {:?}\n", *log4.lock().unwrap());
83
84    // Example 5: Using into_fn after chained operations
85    println!("5. Using into_fn after chained operations");
86    let log5 = Arc::new(Mutex::new(Vec::new()));
87    let l5 = log5.clone();
88    let l6 = log5.clone();
89
90    let chained = BoxConsumer::new(move |x: &i32| {
91        l5.lock().unwrap().push(format!("A: {}", x));
92    })
93    .and_then(move |x: &i32| {
94        l6.lock().unwrap().push(format!("B: {}", x));
95    });
96
97    [1, 2].iter().for_each(chained.into_fn());
98    println!("   Result: {:?}\n", *log5.lock().unwrap());
99
100    println!("=== Demo Complete ===");
101}