Skip to main content

consumer_fn_usage/
consumer_fn_usage.rs

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