Skip to main content

function_family_demo/
function_family_demo.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9
10use qubit_function::{
11    BiFunction,
12    BiFunctionOnce,
13    BiMutatingFunction,
14    BiMutatingFunctionOnce,
15    BoxBiFunction,
16    BoxBiFunctionOnce,
17    BoxBiMutatingFunction,
18    BoxBiMutatingFunctionOnce,
19    BoxFunction,
20    BoxFunctionOnce,
21    BoxMutatingFunction,
22    BoxMutatingFunctionOnce,
23    BoxStatefulFunction,
24    BoxStatefulMutatingFunction,
25    Function,
26    FunctionOnce,
27    MutatingFunction,
28    MutatingFunctionOnce,
29    StatefulFunction,
30    StatefulMutatingFunction,
31};
32
33fn main() {
34    println!("=== Function Family Demo ===\n");
35
36    demo_borrowed_functions();
37    demo_mutating_functions();
38    demo_bi_functions();
39    demo_bi_mutating_functions();
40}
41
42fn demo_borrowed_functions() {
43    println!("--- Borrowed-input functions ---");
44
45    let len = BoxFunction::new(|value: &String| value.len());
46    let value = String::from("qubit");
47    println!("Function length: {}", len.apply(&value));
48    println!("Original value is still available: {value}");
49
50    let greeting = BoxFunctionOnce::new(|name: &String| format!("hello, {name}"));
51    println!("FunctionOnce greeting: {}", greeting.apply(&value));
52
53    let mut call_count = 0;
54    let mut stateful = BoxStatefulFunction::new(move |input: &i32| {
55        call_count += 1;
56        input + call_count
57    });
58    println!("StatefulFunction first call: {}", stateful.apply(&40));
59    println!("StatefulFunction second call: {}", stateful.apply(&40));
60    println!();
61}
62
63fn demo_mutating_functions() {
64    println!("--- Mutating functions ---");
65
66    let push_answer = BoxMutatingFunction::new(|items: &mut Vec<i32>| {
67        items.push(42);
68        items.len()
69    });
70    let mut items = vec![1, 2, 3];
71    println!(
72        "MutatingFunction new length: {}",
73        push_answer.apply(&mut items)
74    );
75    println!("Items after mutation: {items:?}");
76
77    let append_once = BoxMutatingFunctionOnce::new(|text: &mut String| {
78        text.push_str(" once");
79        text.len()
80    });
81    let mut text = String::from("called");
82    println!(
83        "MutatingFunctionOnce length: {}",
84        append_once.apply(&mut text)
85    );
86    println!("Text after one-time mutation: {text}");
87
88    let mut step = 0;
89    let mut stateful = BoxStatefulMutatingFunction::new(move |value: &mut i32| {
90        step += 1;
91        *value += step;
92        *value
93    });
94    let mut value = 40;
95    println!(
96        "StatefulMutatingFunction first call: {}",
97        stateful.apply(&mut value)
98    );
99    println!(
100        "StatefulMutatingFunction second call: {}",
101        stateful.apply(&mut value)
102    );
103    println!();
104}
105
106fn demo_bi_functions() {
107    println!("--- Bi-functions ---");
108
109    let describe =
110        BoxBiFunction::new(|name: &String, score: &i32| format!("{name} scored {score}"));
111    let name = String::from("Alice");
112    let score = 98;
113    println!("BiFunction: {}", describe.apply(&name, &score));
114
115    let once = BoxBiFunctionOnce::new(|left: &String, right: &String| format!("{left}-{right}"));
116    let left = String::from("task");
117    let right = String::from("done");
118    println!("BiFunctionOnce: {}", once.apply(&left, &right));
119    println!();
120}
121
122fn demo_bi_mutating_functions() {
123    println!("--- Bi-mutating functions ---");
124
125    let move_one = BoxBiMutatingFunction::new(|source: &mut Vec<i32>, target: &mut Vec<i32>| {
126        if let Some(value) = source.pop() {
127            target.push(value);
128        }
129        target.len()
130    });
131    let mut source = vec![1, 2, 3];
132    let mut target = vec![10];
133    println!(
134        "BiMutatingFunction target length: {}",
135        move_one.apply(&mut source, &mut target)
136    );
137    println!("Source: {source:?}, target: {target:?}");
138
139    let merge_once = BoxBiMutatingFunctionOnce::new(|left: &mut String, right: &mut String| {
140        left.push_str(right);
141        right.clear();
142        left.len()
143    });
144    let mut left = String::from("hello");
145    let mut right = String::from(" world");
146    println!(
147        "BiMutatingFunctionOnce merged length: {}",
148        merge_once.apply(&mut left, &mut right)
149    );
150    println!("Left: {left}, right is empty: {}", right.is_empty());
151}