Skip to main content

always_predicate_demo/
always_predicate_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 ******************************************************************************/
10use qubit_function::{
11    ArcPredicate,
12    BoxPredicate,
13    Predicate,
14    RcPredicate,
15};
16
17fn main() {
18    println!("=== BoxPredicate always_true/always_false Demo ===\n");
19
20    // BoxPredicate::always_true
21    let always_true: BoxPredicate<i32> = BoxPredicate::always_true();
22    println!("BoxPredicate::always_true():");
23    println!("  test(&42): {}", always_true.test(&42));
24    println!("  test(&-1): {}", always_true.test(&-1));
25    println!("  test(&0): {}", always_true.test(&0));
26    println!("  name: {:?}", always_true.name());
27
28    // BoxPredicate::always_false
29    let always_false: BoxPredicate<i32> = BoxPredicate::always_false();
30    println!("\nBoxPredicate::always_false():");
31    println!("  test(&42): {}", always_false.test(&42));
32    println!("  test(&-1): {}", always_false.test(&-1));
33    println!("  test(&0): {}", always_false.test(&0));
34    println!("  name: {:?}", always_false.name());
35
36    println!("\n=== RcPredicate always_true/always_false Demo ===\n");
37
38    // RcPredicate::always_true
39    let rc_always_true: RcPredicate<String> = RcPredicate::always_true();
40    println!("RcPredicate::always_true():");
41    println!(
42        "  test(&\"hello\"): {}",
43        rc_always_true.test(&"hello".to_string())
44    );
45    println!(
46        "  test(&\"world\"): {}",
47        rc_always_true.test(&"world".to_string())
48    );
49    println!("  name: {:?}", rc_always_true.name());
50
51    // RcPredicate::always_false
52    let rc_always_false: RcPredicate<String> = RcPredicate::always_false();
53    println!("\nRcPredicate::always_false():");
54    println!(
55        "  test(&\"hello\"): {}",
56        rc_always_false.test(&"hello".to_string())
57    );
58    println!(
59        "  test(&\"world\"): {}",
60        rc_always_false.test(&"world".to_string())
61    );
62    println!("  name: {:?}", rc_always_false.name());
63
64    // Can be cloned and reused
65    let rc_clone = rc_always_true.clone();
66    println!("\nAfter cloning, still usable:");
67    println!(
68        "  Original: test(&\"test\"): {}",
69        rc_always_true.test(&"test".to_string())
70    );
71    println!(
72        "  Clone: test(&\"test\"): {}",
73        rc_clone.test(&"test".to_string())
74    );
75
76    println!("\n=== ArcPredicate always_true/always_false Demo ===\n");
77
78    // ArcPredicate::always_true
79    let arc_always_true: ArcPredicate<i32> = ArcPredicate::always_true();
80    println!("ArcPredicate::always_true():");
81    println!("  test(&100): {}", arc_always_true.test(&100));
82    println!("  test(&-100): {}", arc_always_true.test(&-100));
83    println!("  name: {:?}", arc_always_true.name());
84
85    // ArcPredicate::always_false
86    let arc_always_false: ArcPredicate<i32> = ArcPredicate::always_false();
87    println!("\nArcPredicate::always_false():");
88    println!("  test(&100): {}", arc_always_false.test(&100));
89    println!("  test(&-100): {}", arc_always_false.test(&-100));
90    println!("  name: {:?}", arc_always_false.name());
91
92    println!("\n=== Combining with other predicates ===\n");
93
94    // Combining with always_true (AND)
95    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
96    let combined_and_true = is_positive.and(BoxPredicate::always_true());
97    println!("is_positive AND always_true:");
98    println!(
99        "  test(&5): {} (equivalent to is_positive)",
100        combined_and_true.test(&5)
101    );
102    println!(
103        "  test(&-3): {} (equivalent to is_positive)",
104        combined_and_true.test(&-3)
105    );
106
107    // Combining with always_false (AND)
108    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
109    let combined_and_false = is_positive.and(BoxPredicate::always_false());
110    println!("\nis_positive AND always_false:");
111    println!("  test(&5): {} (always false)", combined_and_false.test(&5));
112    println!(
113        "  test(&-3): {} (always false)",
114        combined_and_false.test(&-3)
115    );
116
117    // Combining with always_true (OR)
118    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
119    let combined_or_true = is_positive.or(BoxPredicate::always_true());
120    println!("\nis_positive OR always_true:");
121    println!("  test(&5): {} (always true)", combined_or_true.test(&5));
122    println!("  test(&-3): {} (always true)", combined_or_true.test(&-3));
123
124    // Combining with always_false (OR)
125    let is_positive = BoxPredicate::new(|x: &i32| *x > 0);
126    let combined_or_false = is_positive.or(BoxPredicate::always_false());
127    println!("\nis_positive OR always_false:");
128    println!(
129        "  test(&5): {} (equivalent to is_positive)",
130        combined_or_false.test(&5)
131    );
132    println!(
133        "  test(&-3): {} (equivalent to is_positive)",
134        combined_or_false.test(&-3)
135    );
136
137    println!("\n=== Practical scenarios: Default pass/reject filters ===\n");
138
139    // Scenario 1: Default pass-all filter
140    let numbers = vec![1, 2, 3, 4, 5];
141    let pass_all = BoxPredicate::<i32>::always_true();
142    let filtered: Vec<_> = numbers.iter().copied().filter(pass_all.into_fn()).collect();
143    println!("Default pass all elements: {:?} -> {:?}", numbers, filtered);
144
145    // Scenario 2: Default reject-all filter
146    let numbers = vec![1, 2, 3, 4, 5];
147    let reject_all = BoxPredicate::<i32>::always_false();
148    let filtered: Vec<_> = numbers
149        .iter()
150        .copied()
151        .filter(reject_all.into_fn())
152        .collect();
153    println!(
154        "Default reject all elements: {:?} -> {:?}",
155        numbers, filtered
156    );
157
158    // Scenario 3: Configurable filter
159    fn configurable_filter(enable_filter: bool) -> BoxPredicate<i32> {
160        if enable_filter {
161            BoxPredicate::new(|x: &i32| *x > 3)
162        } else {
163            BoxPredicate::always_true()
164        }
165    }
166
167    let numbers = vec![1, 2, 3, 4, 5];
168
169    let filter_enabled = configurable_filter(true);
170    let filtered: Vec<_> = numbers
171        .iter()
172        .copied()
173        .filter(filter_enabled.into_fn())
174        .collect();
175    println!("\nFilter enabled: {:?} -> {:?}", numbers, filtered);
176
177    let filter_disabled = configurable_filter(false);
178    let filtered: Vec<_> = numbers
179        .iter()
180        .copied()
181        .filter(filter_disabled.into_fn())
182        .collect();
183    println!("Filter disabled: {:?} -> {:?}", numbers, filtered);
184}