Skip to main content

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