consumer_fn_usage/
consumer_fn_usage.rs

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