consumer_once_demo/
consumer_once_demo.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # ConsumerOnce Demo
10//!
11//! Demonstrates the usage of ConsumerOnce trait and its implementations.
12
13use prism3_function::{BoxConsumerOnce, ConsumerOnce, FnConsumerOnceOps};
14use std::sync::{Arc, Mutex};
15
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_once(&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_once(&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_once(&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_once(&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_once(&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_once(&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_once(&-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_once(&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_once(&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_once();
135        box_consumer.accept_once(&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_once());
149        consumer.accept_once(&1);
150        println!(
151            "  BoxConsumerOnce with single value: {:?}\n",
152            *log.lock().unwrap()
153        );
154    }
155
156    println!("=== Demo Complete ===");
157}