prism3_function/
tester.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Tester Type
10//!
11//! Provides tester implementations that test conditions or states and return
12//! boolean values, without accepting input parameters.
13//!
14//! # Overview
15//!
16//! **Tester** is a functional abstraction for testing conditions or states
17//! without accepting input. It can check system status, wait for conditions,
18//! or perform health checks.
19//!
20//! This module implements **Option 3** from the design document: a unified
21//! `Tester` trait with multiple concrete implementations optimized for
22//! different ownership and concurrency scenarios.
23//!
24//! # Core Design Principles
25//!
26//! 1. **Returns boolean**: `Tester` returns `bool` to indicate test results
27//! 2. **Uses `&self`**: Tester is only responsible for "judgment", not
28//!    "state management"
29//! 3. **No TesterOnce**: Very limited use cases, lacks practical examples
30//! 4. **State management is caller's responsibility**: Tester only reads
31//!    state, does not modify state
32//!
33//! # Three Implementations
34//!
35//! - **`BoxTester`**: Single ownership using `Box<dyn Fn() -> bool>`.
36//!   Zero overhead, cannot be cloned. Best for one-time use and builder
37//!   patterns.
38//!
39//! - **`ArcTester`**: Thread-safe shared ownership using
40//!   `Arc<dyn Fn() -> bool + Send + Sync>`. Can be cloned and sent across
41//!   threads. Lock-free overhead.
42//!
43//! - **`RcTester`**: Single-threaded shared ownership using
44//!   `Rc<dyn Fn() -> bool>`. Can be cloned but cannot be sent across
45//!   threads. Lower overhead than `ArcTester`.
46//!
47//! # Comparison with Other Functional Abstractions
48//!
49//! | Type      | Input | Output | self      | Modify? | Use Cases   |
50//! |-----------|-------|--------|-----------|---------|-------------|
51//! | Tester    | None  | `bool` | `&self`   | No      | State Check |
52//! | Predicate | `&T`  | `bool` | `&self`   | No      | Filter      |
53//! | Supplier  | None  | `T`    | `&mut`    | Yes     | Factory     |
54//!
55//! # Examples
56//!
57//! ## Basic State Checking
58//!
59//! ```rust
60//! use prism3_function::{BoxTester, Tester};
61//! use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
62//!
63//! // State managed externally
64//! let count = Arc::new(AtomicUsize::new(0));
65//! let count_clone = Arc::clone(&count);
66//!
67//! let tester = BoxTester::new(move || {
68//!     count_clone.load(Ordering::Relaxed) <= 3
69//! });
70//!
71//! assert!(tester.test());  // true (0)
72//! count.fetch_add(1, Ordering::Relaxed);
73//! assert!(tester.test());  // true (1)
74//! count.fetch_add(1, Ordering::Relaxed);
75//! assert!(tester.test());  // true (2)
76//! count.fetch_add(1, Ordering::Relaxed);
77//! assert!(tester.test());  // true (3)
78//! count.fetch_add(1, Ordering::Relaxed);
79//! assert!(!tester.test()); // false (4)
80//! ```
81//!
82//! ## Logical Combination
83//!
84//! ```rust
85//! use prism3_function::{BoxTester, Tester};
86//! use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
87//!
88//! // 模拟微服务健康检查场景
89//! let cpu_usage = Arc::new(AtomicUsize::new(0));
90//! let memory_usage = Arc::new(AtomicUsize::new(0));
91//! let is_healthy = Arc::new(AtomicBool::new(true));
92//! let is_ready = Arc::new(AtomicBool::new(false));
93//! let max_cpu = 80;
94//! let max_memory = 90;
95//!
96//! let cpu_clone = Arc::clone(&cpu_usage);
97//! let memory_clone = Arc::clone(&memory_usage);
98//! let health_clone = Arc::clone(&is_healthy);
99//! let ready_clone = Arc::clone(&is_ready);
100//!
101//! // 系统资源检查:CPU和内存都在安全范围内
102//! let resources_ok = BoxTester::new(move || {
103//!     cpu_clone.load(Ordering::Relaxed) < max_cpu
104//! })
105//! .and(move || {
106//!     memory_clone.load(Ordering::Relaxed) < max_memory
107//! });
108//!
109//! // 服务状态检查:健康或就绪
110//! let service_ok = BoxTester::new(move || {
111//!     health_clone.load(Ordering::Relaxed)
112//! })
113//! .or(move || {
114//!     ready_clone.load(Ordering::Relaxed)
115//! });
116//!
117//! // 组合条件:资源正常且服务可用
118//! let can_accept_traffic = resources_ok.and(service_ok);
119//!
120//! // 测试不同状态组合
121//! // 初始状态:资源正常且服务健康
122//! cpu_usage.store(50, Ordering::Relaxed);
123//! memory_usage.store(60, Ordering::Relaxed);
124//! assert!(can_accept_traffic.test()); // 资源正常且服务健康
125//!
126//! // 服务不健康但就绪
127//! is_healthy.store(false, Ordering::Relaxed);
128//! is_ready.store(true, Ordering::Relaxed);
129//! assert!(can_accept_traffic.test()); // 资源正常且服务就绪
130//!
131//! // CPU使用率过高
132//! cpu_usage.store(95, Ordering::Relaxed);
133//! assert!(!can_accept_traffic.test()); // 资源超限
134//!
135//! // 服务不健康但就绪
136//! is_healthy.store(false, Ordering::Relaxed);
137//! cpu_usage.store(50, Ordering::Relaxed);
138//! assert!(can_accept_traffic.test()); // 仍然就绪
139//! ```
140//!
141//! ## Thread-Safe Sharing
142//!
143//! ```rust
144//! use prism3_function::{ArcTester, Tester};
145//! use std::thread;
146//!
147//! let shared = ArcTester::new(|| true);
148//! let clone = shared.clone();
149//!
150//! let handle = thread::spawn(move || {
151//!     clone.test()
152//! });
153//!
154//! assert!(handle.join().unwrap());
155//! ```
156//!
157//! # Author
158//!
159//! Hu Haixing
160
161use std::rc::Rc;
162use std::sync::Arc;
163
164// ============================================================================
165// Core Tester Trait
166// ============================================================================
167
168/// Tests whether a state or condition holds
169///
170/// Tester is a functional abstraction for testing states or conditions. It
171/// accepts no parameters and returns a boolean value indicating the test
172/// result of some state or condition.
173///
174/// # Core Characteristics
175///
176/// - **No input parameters**: Captures context through closures
177/// - **Returns boolean**: Indicates test results
178/// - **Uses `&self`**: Does not modify its own state, only reads external
179///   state
180/// - **Repeatable calls**: The same Tester can call `test()` multiple times
181///
182/// # Use Cases
183///
184/// - **State checking**: Check system or service status
185/// - **Condition waiting**: Repeatedly check until conditions are met
186/// - **Health monitoring**: Check system health status
187/// - **Precondition validation**: Verify conditions before operations
188///
189/// # Design Philosophy
190///
191/// Tester's responsibility is "test judgment", not "state management".
192/// State management is the caller's responsibility. Tester only reads state
193/// and returns judgment results.
194///
195/// # Examples
196///
197/// ```rust
198/// use prism3_function::{BoxTester, Tester};
199/// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
200///
201/// // State managed externally
202/// let ready = Arc::new(AtomicBool::new(false));
203/// let ready_clone = Arc::clone(&ready);
204///
205/// // Tester only responsible for reading state
206/// let tester = BoxTester::new(move || {
207///     ready_clone.load(Ordering::Acquire)
208/// });
209///
210/// // Can be called multiple times
211/// assert!(!tester.test());
212/// ready.store(true, Ordering::Release);
213/// assert!(tester.test());
214/// ```
215///
216/// # Author
217///
218/// Hu Haixing
219pub trait Tester {
220    /// Executes the test and returns the test result
221    ///
222    /// This method can be called multiple times without modifying the Tester's
223    /// own state.
224    ///
225    /// # Return Value
226    ///
227    /// Returns `true` if the condition holds, otherwise returns `false`
228    ///
229    /// # Examples
230    ///
231    /// ```rust
232    /// use prism3_function::{BoxTester, Tester};
233    ///
234    /// let tester = BoxTester::new(|| true);
235    /// assert!(tester.test());
236    /// ```
237    fn test(&self) -> bool;
238
239    /// Converts this tester to `BoxTester`
240    ///
241    /// # Return Value
242    ///
243    /// A `BoxTester` that wraps this tester
244    ///
245    /// # Examples
246    ///
247    /// ```rust
248    /// use prism3_function::{Tester, BoxTester};
249    ///
250    /// let closure = || true;
251    /// let boxed: BoxTester = closure.into_box();
252    /// ```
253    fn into_box(self) -> BoxTester
254    where
255        Self: Sized + 'static;
256
257    /// Converts this tester to `RcTester`
258    ///
259    /// # Return Value
260    ///
261    /// A `RcTester` that wraps this tester
262    ///
263    /// # Examples
264    ///
265    /// ```rust
266    /// use prism3_function::{Tester, RcTester};
267    ///
268    /// let closure = || true;
269    /// let rc: RcTester = closure.into_rc();
270    /// ```
271    fn into_rc(self) -> RcTester
272    where
273        Self: Sized + 'static;
274
275    /// Converts this tester to `ArcTester`
276    ///
277    /// # Return Value
278    ///
279    /// An `ArcTester` that wraps this tester
280    ///
281    /// # Examples
282    ///
283    /// ```rust
284    /// use prism3_function::{Tester, ArcTester};
285    ///
286    /// let closure = || true;
287    /// let arc: ArcTester = closure.into_arc();
288    /// ```
289    fn into_arc(self) -> ArcTester
290    where
291        Self: Sized + Send + Sync + 'static,
292    {
293        panic!("into_arc() is not supported for this type")
294    }
295}
296
297// ============================================================================
298// BoxTester: Single Ownership Implementation
299// ============================================================================
300
301/// Single ownership Tester implemented using `Box`
302///
303/// `BoxTester` wraps a closure in `Box<dyn Fn() -> bool>`, providing single
304/// ownership semantics with no additional allocation overhead beyond the
305/// initial boxing.
306///
307/// # Characteristics
308///
309/// - **Single ownership**: Cannot be cloned
310/// - **Zero overhead**: Single heap allocation
311/// - **Consuming combination**: `and()`/`or()`/`not()` consume `self`
312/// - **Type flexibility**: Accepts any `Tester` implementation
313///
314/// # Use Cases
315///
316/// - One-time testing scenarios
317/// - Builder patterns requiring ownership transfer
318/// - Simple state checking without sharing
319/// - Chained calls with ownership transfer
320///
321/// # Examples
322///
323/// ```rust
324/// use prism3_function::{BoxTester, Tester};
325/// use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
326///
327/// // State managed externally
328/// let count = Arc::new(AtomicUsize::new(0));
329/// let count_clone = Arc::clone(&count);
330///
331/// let tester = BoxTester::new(move || {
332///     count_clone.load(Ordering::Relaxed) < 3
333/// });
334///
335/// assert!(tester.test());
336/// count.fetch_add(1, Ordering::Relaxed);
337/// assert!(tester.test());
338/// count.fetch_add(1, Ordering::Relaxed);
339/// assert!(tester.test());
340/// count.fetch_add(1, Ordering::Relaxed);
341/// assert!(!tester.test());
342///
343/// // Logical combination
344/// let combined = BoxTester::new(|| true)
345///     .and(|| false)
346///     .or(|| true);
347/// assert!(combined.test());
348/// ```
349///
350/// # Author
351///
352/// Hu Haixing
353pub struct BoxTester {
354    func: Box<dyn Fn() -> bool>,
355}
356
357impl BoxTester {
358    /// Creates a new `BoxTester` from a closure
359    ///
360    /// # Type Parameters
361    ///
362    /// * `F` - Closure type implementing `Fn() -> bool`
363    ///
364    /// # Parameters
365    ///
366    /// * `f` - The closure to wrap
367    ///
368    /// # Return Value
369    ///
370    /// A new `BoxTester` instance
371    ///
372    /// # Examples
373    ///
374    /// ```rust
375    /// use prism3_function::BoxTester;
376    ///
377    /// let tester = BoxTester::new(|| true);
378    /// ```
379    pub fn new<F>(f: F) -> Self
380    where
381        F: Fn() -> bool + 'static,
382    {
383        BoxTester { func: Box::new(f) }
384    }
385
386    /// Combines this tester with another tester using logical AND
387    ///
388    /// Returns a new `BoxTester` that returns `true` only when both tests
389    /// pass. Short-circuit evaluation: if the first test fails, the second
390    /// will not be executed.
391    ///
392    /// # Type Parameters
393    ///
394    /// * `T` - Type implementing `Tester`
395    ///
396    /// # Parameters
397    ///
398    /// * `next` - The tester to combine with
399    ///
400    /// # Return Value
401    ///
402    /// A new `BoxTester` representing logical AND
403    ///
404    /// # Examples
405    ///
406    /// ```rust
407    /// use prism3_function::{BoxTester, Tester};
408    /// use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
409    ///
410    /// // 模拟服务状态
411    /// let request_count = Arc::new(AtomicUsize::new(0));
412    /// let is_available = Arc::new(AtomicBool::new(true));
413    /// let max_requests = 1000;
414    ///
415    /// let count_clone = Arc::clone(&request_count);
416    /// let available_clone = Arc::clone(&is_available);
417    ///
418    /// // 服务可用且请求数未超限
419    /// let service_ok = BoxTester::new(move || {
420    ///     available_clone.load(Ordering::Relaxed)
421    /// })
422    /// .and(move || {
423    ///     count_clone.load(Ordering::Relaxed) < max_requests
424    /// });
425    ///
426    /// // 初始状态:可用且请求数为0
427    /// assert!(service_ok.test());
428    ///
429    /// // 模拟请求增加
430    /// request_count.store(500, Ordering::Relaxed);
431    /// assert!(service_ok.test());
432    ///
433    /// // 请求数超限
434    /// request_count.store(1500, Ordering::Relaxed);
435    /// assert!(!service_ok.test());
436    ///
437    /// // 服务不可用
438    /// is_available.store(false, Ordering::Relaxed);
439    /// assert!(!service_ok.test());
440    /// ```
441    pub fn and<T>(self, next: T) -> BoxTester
442    where
443        T: Tester + 'static,
444    {
445        let first = self.func;
446        let second = next;
447        BoxTester::new(move || first() && second.test())
448    }
449
450    /// Combines this tester with another tester using logical OR
451    ///
452    /// Returns a new `BoxTester` that returns `true` if either test passes.
453    /// Short-circuit evaluation: if the first test passes, the second will
454    /// not be executed.
455    ///
456    /// # Type Parameters
457    ///
458    /// * `T` - Type implementing `Tester`
459    ///
460    /// # Parameters
461    ///
462    /// * `next` - The tester to combine with
463    ///
464    /// # Return Value
465    ///
466    /// A new `BoxTester` representing logical OR
467    ///
468    /// # Examples
469    ///
470    /// ```rust
471    /// use prism3_function::{BoxTester, Tester};
472    /// use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
473    ///
474    /// // 模拟服务状态
475    /// let request_count = Arc::new(AtomicUsize::new(0));
476    /// let is_healthy = Arc::new(AtomicBool::new(true));
477    /// let max_requests = 100;
478    ///
479    /// let count_clone = Arc::clone(&request_count);
480    /// let health_clone = Arc::clone(&is_healthy);
481    ///
482    /// // 服务健康或请求数较少
483    /// let can_serve = BoxTester::new(move || {
484    ///     health_clone.load(Ordering::Relaxed)
485    /// })
486    /// .or(move || {
487    ///     count_clone.load(Ordering::Relaxed) < max_requests
488    /// });
489    ///
490    /// // 初始状态:健康且请求数为0
491    /// assert!(can_serve.test());
492    ///
493    /// // 请求数增加但仍在限制内
494    /// request_count.store(50, Ordering::Relaxed);
495    /// assert!(can_serve.test());
496    ///
497    /// // 请求数超限但服务健康
498    /// request_count.store(150, Ordering::Relaxed);
499    /// assert!(can_serve.test()); // 仍然健康
500    ///
501    /// // 服务不健康但请求数少
502    /// is_healthy.store(false, Ordering::Relaxed);
503    /// request_count.store(50, Ordering::Relaxed);
504    /// assert!(can_serve.test()); // 请求数少
505    ///
506    /// // 既不健康又请求数多
507    /// request_count.store(150, Ordering::Relaxed);
508    /// assert!(!can_serve.test());
509    /// ```
510    pub fn or<T>(self, next: T) -> BoxTester
511    where
512        T: Tester + 'static,
513    {
514        let first = self.func;
515        let second = next;
516        BoxTester::new(move || first() || second.test())
517    }
518
519    /// Negates the result of this tester
520    ///
521    /// Returns a new `BoxTester` that returns the opposite value of the
522    /// original test result.
523    ///
524    /// # Return Value
525    ///
526    /// A new `BoxTester` representing logical NOT
527    ///
528    /// # Examples
529    ///
530    /// ```rust
531    /// use prism3_function::{BoxTester, Tester};
532    /// use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
533    ///
534    /// // 模拟资源使用情况
535    /// let memory_usage = Arc::new(AtomicUsize::new(0));
536    /// let max_memory = 1024; // MB
537    ///
538    /// let memory_clone = Arc::clone(&memory_usage);
539    ///
540    /// // 内存使用是否超限
541    /// let memory_ok = BoxTester::new(move || {
542    ///     memory_clone.load(Ordering::Relaxed) <= max_memory
543    /// });
544    ///
545    /// // 初始状态:内存使用正常
546    /// memory_usage.store(512, Ordering::Relaxed);
547    /// assert!(memory_ok.test());
548    ///
549    /// // 内存使用是否超限(取反)
550    /// let memory_critical = memory_ok.not();
551    /// assert!(!memory_critical.test());
552    ///
553    /// // 内存使用超限
554    /// memory_usage.store(2048, Ordering::Relaxed);
555    /// assert!(memory_critical.test());
556    /// ```
557    #[allow(clippy::should_implement_trait)]
558    pub fn not(self) -> BoxTester {
559        let func = self.func;
560        BoxTester::new(move || !func())
561    }
562
563    /// Combines this tester with another tester using logical NAND
564    ///
565    /// Returns a new `BoxTester` that returns `true` unless both tests pass.
566    /// Equivalent to `!(self AND other)`.
567    ///
568    /// # Type Parameters
569    ///
570    /// * `T` - Type implementing `Tester`
571    ///
572    /// # Parameters
573    ///
574    /// * `next` - The tester to combine with
575    ///
576    /// # Return Value
577    ///
578    /// A new `BoxTester` representing logical NAND
579    ///
580    /// # Examples
581    ///
582    /// ```rust
583    /// use prism3_function::{BoxTester, Tester};
584    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
585    ///
586    /// let flag1 = Arc::new(AtomicBool::new(true));
587    /// let flag2 = Arc::new(AtomicBool::new(true));
588    ///
589    /// let flag1_clone = Arc::clone(&flag1);
590    /// let flag2_clone = Arc::clone(&flag2);
591    ///
592    /// let nand = BoxTester::new(move || {
593    ///     flag1_clone.load(Ordering::Relaxed)
594    /// })
595    /// .nand(move || {
596    ///     flag2_clone.load(Ordering::Relaxed)
597    /// });
598    ///
599    /// // 两个都为 true 时返回 false
600    /// assert!(!nand.test());
601    ///
602    /// // 至少一个为 false 时返回 true
603    /// flag1.store(false, Ordering::Relaxed);
604    /// assert!(nand.test());
605    /// ```
606    pub fn nand<T>(self, next: T) -> BoxTester
607    where
608        T: Tester + 'static,
609    {
610        let first = self.func;
611        let second = next;
612        BoxTester::new(move || !(first() && second.test()))
613    }
614
615    /// Combines this tester with another tester using logical XOR
616    ///
617    /// Returns a new `BoxTester` that returns `true` if exactly one test
618    /// passes.
619    ///
620    /// # Type Parameters
621    ///
622    /// * `T` - Type implementing `Tester`
623    ///
624    /// # Parameters
625    ///
626    /// * `next` - The tester to combine with
627    ///
628    /// # Return Value
629    ///
630    /// A new `BoxTester` representing logical XOR
631    ///
632    /// # Examples
633    ///
634    /// ```rust
635    /// use prism3_function::{BoxTester, Tester};
636    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
637    ///
638    /// let flag1 = Arc::new(AtomicBool::new(true));
639    /// let flag2 = Arc::new(AtomicBool::new(false));
640    ///
641    /// let flag1_clone1 = Arc::clone(&flag1);
642    /// let flag2_clone1 = Arc::clone(&flag2);
643    ///
644    /// let xor = BoxTester::new(move || {
645    ///     flag1_clone1.load(Ordering::Relaxed)
646    /// })
647    /// .xor(move || {
648    ///     flag2_clone1.load(Ordering::Relaxed)
649    /// });
650    ///
651    /// // 一个 true 一个 false 时返回 true
652    /// assert!(xor.test());
653    ///
654    /// // 两个都为 true 时返回 false
655    /// flag2.store(true, Ordering::Relaxed);
656    /// assert!(!xor.test());
657    ///
658    /// // 两个都为 false 时返回 false
659    /// flag1.store(false, Ordering::Relaxed);
660    /// flag2.store(false, Ordering::Relaxed);
661    /// assert!(!xor.test());
662    /// ```
663    pub fn xor<T>(self, next: T) -> BoxTester
664    where
665        T: Tester + 'static,
666    {
667        let first = self.func;
668        let second = next;
669        BoxTester::new(move || first() ^ second.test())
670    }
671
672    /// Combines this tester with another tester using logical NOR
673    ///
674    /// Returns a new `BoxTester` that returns `true` only when both tests
675    /// fail. Equivalent to `!(self OR other)`.
676    ///
677    /// # Type Parameters
678    ///
679    /// * `T` - Type implementing `Tester`
680    ///
681    /// # Parameters
682    ///
683    /// * `next` - The tester to combine with
684    ///
685    /// # Return Value
686    ///
687    /// A new `BoxTester` representing logical NOR
688    ///
689    /// # Examples
690    ///
691    /// ```rust
692    /// use prism3_function::{BoxTester, Tester};
693    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
694    ///
695    /// let flag1 = Arc::new(AtomicBool::new(false));
696    /// let flag2 = Arc::new(AtomicBool::new(false));
697    ///
698    /// let flag1_clone = Arc::clone(&flag1);
699    /// let flag2_clone = Arc::clone(&flag2);
700    ///
701    /// let nor = BoxTester::new(move || {
702    ///     flag1_clone.load(Ordering::Relaxed)
703    /// })
704    /// .nor(move || {
705    ///     flag2_clone.load(Ordering::Relaxed)
706    /// });
707    ///
708    /// // 两个都为 false 时返回 true
709    /// assert!(nor.test());
710    ///
711    /// // 至少一个为 true 时返回 false
712    /// flag1.store(true, Ordering::Relaxed);
713    /// assert!(!nor.test());
714    /// ```
715    pub fn nor<T>(self, next: T) -> BoxTester
716    where
717        T: Tester + 'static,
718    {
719        let first = self.func;
720        let second = next;
721        BoxTester::new(move || !(first() || second.test()))
722    }
723}
724
725impl Tester for BoxTester {
726    fn test(&self) -> bool {
727        (self.func)()
728    }
729
730    fn into_box(self) -> BoxTester {
731        self
732    }
733
734    fn into_rc(self) -> RcTester {
735        let func = self.func;
736        RcTester {
737            func: Rc::new(func),
738        }
739    }
740
741    fn into_arc(self) -> ArcTester {
742        // Note: This conversion is impossible because Box<dyn Fn() -> bool>
743        // may not implement Send + Sync. Users should create ArcTester
744        // directly.
745        panic!(
746            "Cannot convert BoxTester to ArcTester. Create ArcTester \
747                directly with ArcTester::new()"
748        )
749    }
750}
751
752// ============================================================================
753// ArcTester: Thread-Safe Shared Ownership Implementation
754// ============================================================================
755
756/// Thread-safe shared ownership Tester implemented using `Arc`
757///
758/// `ArcTester` wraps a closure in `Arc<dyn Fn() -> bool + Send + Sync>`,
759/// allowing the tester to be cloned and safely shared across threads.
760///
761/// # Characteristics
762///
763/// - **Shared ownership**: Can be cloned
764/// - **Thread-safe**: Can be sent across threads
765/// - **Lock-free overhead**: Uses `Fn` without needing `Mutex`
766/// - **Borrowing combination**: `and()`/`or()`/`not()` borrow `&self`
767///
768/// # Use Cases
769///
770/// - Multi-threaded testing scenarios
771/// - Health checks shared across threads
772/// - Test states requiring concurrent access
773/// - Background monitoring tasks
774///
775/// # Examples
776///
777/// ```rust
778/// use prism3_function::{ArcTester, Tester};
779/// use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
780/// use std::thread;
781///
782/// // Shared atomic counter
783/// let counter = Arc::new(AtomicUsize::new(0));
784/// let counter_clone = Arc::clone(&counter);
785///
786/// let shared = ArcTester::new(move || {
787///     counter_clone.load(Ordering::Relaxed) <= 5
788/// });
789///
790/// let clone = shared.clone();
791/// let handle = thread::spawn(move || {
792///     clone.test()
793/// });
794///
795/// assert!(handle.join().unwrap());
796/// counter.fetch_add(1, Ordering::Relaxed);
797/// assert!(shared.test());
798/// ```
799///
800/// # Author
801///
802/// Hu Haixing
803pub struct ArcTester {
804    func: Arc<dyn Fn() -> bool + Send + Sync>,
805}
806
807impl ArcTester {
808    /// Creates a new `ArcTester` from a closure
809    ///
810    /// # Type Parameters
811    ///
812    /// * `F` - Closure type implementing `Fn() -> bool + Send + Sync`
813    ///
814    /// # Parameters
815    ///
816    /// * `f` - The closure to wrap
817    ///
818    /// # Return Value
819    ///
820    /// A new `ArcTester` instance
821    ///
822    /// # Examples
823    ///
824    /// ```rust
825    /// use prism3_function::ArcTester;
826    ///
827    /// let tester = ArcTester::new(|| true);
828    /// ```
829    pub fn new<F>(f: F) -> Self
830    where
831        F: Fn() -> bool + Send + Sync + 'static,
832    {
833        ArcTester { func: Arc::new(f) }
834    }
835
836    /// Combines this tester with another tester using logical AND
837    ///
838    /// Returns a new `ArcTester` that returns `true` only when both tests
839    /// pass. Borrows `&self`, so the original tester remains available.
840    ///
841    /// # Parameters
842    ///
843    /// * `next` - The tester to combine with
844    ///
845    /// # Return Value
846    ///
847    /// A new `ArcTester` representing logical AND
848    ///
849    /// # Examples
850    ///
851    /// ```rust
852    /// use prism3_function::{ArcTester, Tester};
853    /// use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
854    /// use std::thread;
855    ///
856    /// // 模拟数据库连接池状态
857    /// let active_connections = Arc::new(AtomicUsize::new(0));
858    /// let is_pool_healthy = Arc::new(AtomicBool::new(true));
859    /// let max_connections = 50;
860    ///
861    /// let conn_clone = Arc::clone(&active_connections);
862    /// let health_clone = Arc::clone(&is_pool_healthy);
863    ///
864    /// // 连接池健康检查
865    /// let pool_healthy = ArcTester::new(move || {
866    ///     health_clone.load(Ordering::Relaxed)
867    /// });
868    ///
869    /// // 连接数检查
870    /// let conn_ok = ArcTester::new(move || {
871    ///     conn_clone.load(Ordering::Relaxed) < max_connections
872    /// });
873    ///
874    /// // 组合检查:连接池健康且连接数未超限
875    /// let pool_ready = pool_healthy.and(&conn_ok);
876    ///
877    /// // 多线程测试
878    /// let pool_ready_clone = pool_ready.clone();
879    /// let handle = thread::spawn(move || {
880    ///     pool_ready_clone.test()
881    /// });
882    ///
883    /// // 初始状态应该通过
884    /// assert!(handle.join().unwrap());
885    /// assert!(pool_ready.test());
886    ///
887    /// // 连接数超限
888    /// active_connections.store(60, Ordering::Relaxed);
889    /// assert!(!pool_ready.test());
890    ///
891    /// // 连接池不健康
892    /// is_pool_healthy.store(false, Ordering::Relaxed);
893    /// assert!(!pool_ready.test());
894    /// ```
895    pub fn and(&self, next: &ArcTester) -> ArcTester {
896        let first = Arc::clone(&self.func);
897        let second = Arc::clone(&next.func);
898        ArcTester {
899            func: Arc::new(move || first() && second()),
900        }
901    }
902
903    /// Combines this tester with another tester using logical OR
904    ///
905    /// Returns a new `ArcTester` that returns `true` if either test passes.
906    /// Borrows `&self`, so the original tester remains available.
907    ///
908    /// # Parameters
909    ///
910    /// * `next` - The tester to combine with
911    ///
912    /// # Return Value
913    ///
914    /// A new `ArcTester` representing logical OR
915    ///
916    /// # Examples
917    ///
918    /// ```rust
919    /// use prism3_function::{ArcTester, Tester};
920    /// use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
921    /// use std::thread;
922    ///
923    /// // 模拟负载均衡器状态
924    /// let server_load = Arc::new(AtomicUsize::new(0));
925    /// let is_server_healthy = Arc::new(AtomicBool::new(true));
926    /// let max_load = 80;
927    /// let emergency_mode = Arc::new(AtomicBool::new(false));
928    ///
929    /// let load_clone = Arc::clone(&server_load);
930    /// let health_clone = Arc::clone(&is_server_healthy);
931    /// let emergency_clone = Arc::clone(&emergency_mode);
932    ///
933    /// // 服务器负载低
934    /// let low_load = ArcTester::new(move || {
935    ///     load_clone.load(Ordering::Relaxed) < max_load
936    /// });
937    ///
938    /// // 紧急模式检查
939    /// let emergency_check = ArcTester::new(move || {
940    ///     emergency_clone.load(Ordering::Relaxed)
941    /// });
942    ///
943    /// // 服务器健康检查
944    /// let server_healthy = ArcTester::new(move || {
945    ///     health_clone.load(Ordering::Relaxed)
946    /// });
947    ///
948    /// // 紧急模式或服务器健康
949    /// let can_handle_requests = emergency_check.or(&server_healthy);
950    ///
951    /// // 组合条件:负载低或可以处理请求
952    /// let should_route_here = low_load.or(&can_handle_requests);
953    ///
954    /// // 多线程测试
955    /// let router_clone = should_route_here.clone();
956    /// let handle = thread::spawn(move || {
957    ///     router_clone.test()
958    /// });
959    ///
960    /// // 初始状态:负载低且健康
961    /// assert!(handle.join().unwrap());
962    /// assert!(should_route_here.test());
963    ///
964    /// // 负载高但服务器健康
965    /// server_load.store(90, Ordering::Relaxed);
966    /// assert!(should_route_here.test()); // 仍然健康
967    ///
968    /// // 服务器不健康但紧急模式
969    /// is_server_healthy.store(false, Ordering::Relaxed);
970    /// emergency_mode.store(true, Ordering::Relaxed);
971    /// assert!(should_route_here.test()); // 紧急模式
972    ///
973    /// // 既不健康又非紧急模式
974    /// emergency_mode.store(false, Ordering::Relaxed);
975    /// assert!(!should_route_here.test());
976    /// ```
977    pub fn or(&self, next: &ArcTester) -> ArcTester {
978        let first = Arc::clone(&self.func);
979        let second = Arc::clone(&next.func);
980        ArcTester {
981            func: Arc::new(move || first() || second()),
982        }
983    }
984
985    /// Negates the result of this tester
986    ///
987    /// Returns a new `ArcTester` that returns the opposite value of the
988    /// original test result. Borrows `&self`, so the original tester remains
989    /// available.
990    ///
991    /// # Return Value
992    ///
993    /// A new `ArcTester` representing logical NOT
994    ///
995    /// # Examples
996    ///
997    /// ```rust
998    /// use prism3_function::{ArcTester, Tester};
999    /// use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
1000    /// use std::thread;
1001    ///
1002    /// // 模拟任务队列状态
1003    /// let pending_tasks = Arc::new(AtomicUsize::new(0));
1004    /// let max_queue_size = 100;
1005    ///
1006    /// let tasks_clone = Arc::clone(&pending_tasks);
1007    ///
1008    /// // 队列未满
1009    /// let queue_available = ArcTester::new(move || {
1010    ///     tasks_clone.load(Ordering::Relaxed) < max_queue_size
1011    /// });
1012    ///
1013    /// // 队列已满(取反)
1014    /// let queue_full = queue_available.not();
1015    ///
1016    /// // 多线程测试
1017    /// let queue_full_clone = queue_full.clone();
1018    /// let handle = thread::spawn(move || {
1019    ///     queue_full_clone.test()
1020    /// });
1021    ///
1022    /// // 初始状态:队列未满
1023    /// pending_tasks.store(50, Ordering::Relaxed);
1024    /// assert!(queue_available.test());
1025    /// assert!(!handle.join().unwrap());
1026    /// assert!(!queue_full.test());
1027    ///
1028    /// // 队列接近满载
1029    /// pending_tasks.store(95, Ordering::Relaxed);
1030    /// assert!(queue_available.test());
1031    /// assert!(!queue_full.test());
1032    ///
1033    /// // 队列已满
1034    /// pending_tasks.store(120, Ordering::Relaxed);
1035    /// assert!(!queue_available.test());
1036    /// assert!(queue_full.test());
1037    /// ```
1038    #[allow(clippy::should_implement_trait)]
1039    pub fn not(&self) -> ArcTester {
1040        let func = Arc::clone(&self.func);
1041        ArcTester {
1042            func: Arc::new(move || !func()),
1043        }
1044    }
1045
1046    /// Combines this tester with another tester using logical NAND
1047    ///
1048    /// Returns a new `ArcTester` that returns `true` unless both tests pass.
1049    /// Borrows `&self`, so the original tester remains available.
1050    ///
1051    /// # Parameters
1052    ///
1053    /// * `next` - The tester to combine with
1054    ///
1055    /// # Return Value
1056    ///
1057    /// A new `ArcTester` representing logical NAND
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```rust
1062    /// use prism3_function::{ArcTester, Tester};
1063    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
1064    /// use std::thread;
1065    ///
1066    /// let flag1 = Arc::new(AtomicBool::new(true));
1067    /// let flag2 = Arc::new(AtomicBool::new(true));
1068    ///
1069    /// let flag1_clone = Arc::clone(&flag1);
1070    /// let flag2_clone = Arc::clone(&flag2);
1071    ///
1072    /// let tester1 = ArcTester::new(move || {
1073    ///     flag1_clone.load(Ordering::Relaxed)
1074    /// });
1075    ///
1076    /// let tester2 = ArcTester::new(move || {
1077    ///     flag2_clone.load(Ordering::Relaxed)
1078    /// });
1079    ///
1080    /// let nand = tester1.nand(&tester2);
1081    ///
1082    /// // 两个都为 true 时返回 false
1083    /// assert!(!nand.test());
1084    ///
1085    /// // 至少一个为 false 时返回 true
1086    /// flag1.store(false, Ordering::Relaxed);
1087    /// assert!(nand.test());
1088    ///
1089    /// // 原始 tester 仍然可用
1090    /// assert!(!tester1.test());
1091    /// assert!(tester2.test());
1092    /// ```
1093    pub fn nand(&self, next: &ArcTester) -> ArcTester {
1094        let first = Arc::clone(&self.func);
1095        let second = Arc::clone(&next.func);
1096        ArcTester {
1097            func: Arc::new(move || !(first() && second())),
1098        }
1099    }
1100
1101    /// Combines this tester with another tester using logical XOR
1102    ///
1103    /// Returns a new `ArcTester` that returns `true` if exactly one test
1104    /// passes. Borrows `&self`, so the original tester remains available.
1105    ///
1106    /// # Parameters
1107    ///
1108    /// * `next` - The tester to combine with
1109    ///
1110    /// # Return Value
1111    ///
1112    /// A new `ArcTester` representing logical XOR
1113    ///
1114    /// # Examples
1115    ///
1116    /// ```rust
1117    /// use prism3_function::{ArcTester, Tester};
1118    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
1119    /// use std::thread;
1120    ///
1121    /// let flag1 = Arc::new(AtomicBool::new(true));
1122    /// let flag2 = Arc::new(AtomicBool::new(false));
1123    ///
1124    /// let flag1_clone = Arc::clone(&flag1);
1125    /// let flag2_clone = Arc::clone(&flag2);
1126    ///
1127    /// let tester1 = ArcTester::new(move || {
1128    ///     flag1_clone.load(Ordering::Relaxed)
1129    /// });
1130    ///
1131    /// let tester2 = ArcTester::new(move || {
1132    ///     flag2_clone.load(Ordering::Relaxed)
1133    /// });
1134    ///
1135    /// let xor = tester1.xor(&tester2);
1136    ///
1137    /// // 一个 true 一个 false 时返回 true
1138    /// assert!(xor.test());
1139    ///
1140    /// // 两个都为 true 时返回 false
1141    /// flag2.store(true, Ordering::Relaxed);
1142    /// assert!(!xor.test());
1143    ///
1144    /// // 两个都为 false 时返回 false
1145    /// flag1.store(false, Ordering::Relaxed);
1146    /// flag2.store(false, Ordering::Relaxed);
1147    /// assert!(!xor.test());
1148    ///
1149    /// // 原始 tester 仍然可用
1150    /// assert!(!tester1.test());
1151    /// assert!(!tester2.test());
1152    /// ```
1153    pub fn xor(&self, next: &ArcTester) -> ArcTester {
1154        let first = Arc::clone(&self.func);
1155        let second = Arc::clone(&next.func);
1156        ArcTester {
1157            func: Arc::new(move || first() ^ second()),
1158        }
1159    }
1160
1161    /// Combines this tester with another tester using logical NOR
1162    ///
1163    /// Returns a new `ArcTester` that returns `true` only when both tests
1164    /// fail. Borrows `&self`, so the original tester remains available.
1165    ///
1166    /// # Parameters
1167    ///
1168    /// * `next` - The tester to combine with
1169    ///
1170    /// # Return Value
1171    ///
1172    /// A new `ArcTester` representing logical NOR
1173    ///
1174    /// # Examples
1175    ///
1176    /// ```rust
1177    /// use prism3_function::{ArcTester, Tester};
1178    /// use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
1179    /// use std::thread;
1180    ///
1181    /// let flag1 = Arc::new(AtomicBool::new(false));
1182    /// let flag2 = Arc::new(AtomicBool::new(false));
1183    ///
1184    /// let flag1_clone = Arc::clone(&flag1);
1185    /// let flag2_clone = Arc::clone(&flag2);
1186    ///
1187    /// let tester1 = ArcTester::new(move || {
1188    ///     flag1_clone.load(Ordering::Relaxed)
1189    /// });
1190    ///
1191    /// let tester2 = ArcTester::new(move || {
1192    ///     flag2_clone.load(Ordering::Relaxed)
1193    /// });
1194    ///
1195    /// let nor = tester1.nor(&tester2);
1196    ///
1197    /// // 两个都为 false 时返回 true
1198    /// assert!(nor.test());
1199    ///
1200    /// // 至少一个为 true 时返回 false
1201    /// flag1.store(true, Ordering::Relaxed);
1202    /// assert!(!nor.test());
1203    ///
1204    /// // 原始 tester 仍然可用
1205    /// assert!(tester1.test());
1206    /// assert!(!tester2.test());
1207    /// ```
1208    pub fn nor(&self, next: &ArcTester) -> ArcTester {
1209        let first = Arc::clone(&self.func);
1210        let second = Arc::clone(&next.func);
1211        ArcTester {
1212            func: Arc::new(move || !(first() || second())),
1213        }
1214    }
1215}
1216
1217impl Tester for ArcTester {
1218    fn test(&self) -> bool {
1219        (self.func)()
1220    }
1221
1222    fn into_box(self) -> BoxTester {
1223        let func = self.func;
1224        BoxTester {
1225            func: Box::new(move || func()),
1226        }
1227    }
1228
1229    fn into_rc(self) -> RcTester {
1230        let func = self.func;
1231        RcTester {
1232            func: Rc::new(move || func()),
1233        }
1234    }
1235
1236    fn into_arc(self) -> ArcTester {
1237        self
1238    }
1239}
1240
1241impl Clone for ArcTester {
1242    /// Creates a clone of this `ArcTester`.
1243    ///
1244    /// The cloned instance shares the same underlying function with
1245    /// the original, allowing multiple references to the same test
1246    /// logic.
1247    fn clone(&self) -> Self {
1248        Self {
1249            func: Arc::clone(&self.func),
1250        }
1251    }
1252}
1253
1254// ============================================================================
1255// RcTester: Single-Threaded Shared Ownership Implementation
1256// ============================================================================
1257
1258/// Single-threaded shared ownership Tester implemented using `Rc`
1259///
1260/// `RcTester` wraps a closure in `Rc<dyn Fn() -> bool>`, allowing the tester
1261/// to be cloned and shared within a single thread. Since it doesn't use atomic
1262/// operations, it has lower overhead than `ArcTester`.
1263///
1264/// # Characteristics
1265///
1266/// - **Shared ownership**: Can be cloned
1267/// - **Single-threaded**: Cannot be sent across threads
1268/// - **Low overhead**: Uses `Fn` without needing `RefCell`
1269/// - **Borrowing combination**: `and()`/`or()`/`not()` borrow `&self`
1270///
1271/// # Use Cases
1272///
1273/// - Single-threaded testing scenarios requiring sharing
1274/// - Event-driven systems (single-threaded)
1275/// - Callback-intensive code requiring cloneable tests
1276/// - Performance-sensitive single-threaded code
1277///
1278/// # Examples
1279///
1280/// ```rust
1281/// use prism3_function::{RcTester, Tester};
1282///
1283/// let shared = RcTester::new(|| true);
1284///
1285/// // Clone for multiple uses
1286/// let clone1 = shared.clone();
1287/// let clone2 = shared.clone();
1288///
1289/// // Non-consuming combination
1290/// let combined = shared.and(&clone1);
1291/// ```
1292///
1293/// # Author
1294///
1295/// Hu Haixing
1296pub struct RcTester {
1297    func: Rc<dyn Fn() -> bool>,
1298}
1299
1300impl RcTester {
1301    /// Creates a new `RcTester` from a closure
1302    ///
1303    /// # Type Parameters
1304    ///
1305    /// * `F` - Closure type implementing `Fn() -> bool`
1306    ///
1307    /// # Parameters
1308    ///
1309    /// * `f` - The closure to wrap
1310    ///
1311    /// # Return Value
1312    ///
1313    /// A new `RcTester` instance
1314    ///
1315    /// # Examples
1316    ///
1317    /// ```rust
1318    /// use prism3_function::RcTester;
1319    ///
1320    /// let tester = RcTester::new(|| true);
1321    /// ```
1322    pub fn new<F>(f: F) -> Self
1323    where
1324        F: Fn() -> bool + 'static,
1325    {
1326        RcTester { func: Rc::new(f) }
1327    }
1328
1329    /// Combines this tester with another tester using logical AND
1330    ///
1331    /// Returns a new `RcTester` that returns `true` only when both tests
1332    /// pass. Borrows `&self`, so the original tester remains available.
1333    ///
1334    /// # Parameters
1335    ///
1336    /// * `next` - The tester to combine with
1337    ///
1338    /// # Return Value
1339    ///
1340    /// A new `RcTester` representing logical AND
1341    ///
1342    /// # Examples
1343    ///
1344    /// ```rust
1345    /// use prism3_function::{RcTester, Tester};
1346    ///
1347    /// let first = RcTester::new(|| true);
1348    /// let second = RcTester::new(|| true);
1349    /// let combined = first.and(&second);
1350    /// // first and second are still available
1351    /// ```
1352    pub fn and(&self, next: &RcTester) -> RcTester {
1353        let first = Rc::clone(&self.func);
1354        let second = Rc::clone(&next.func);
1355        RcTester {
1356            func: Rc::new(move || first() && second()),
1357        }
1358    }
1359
1360    /// Combines this tester with another tester using logical OR
1361    ///
1362    /// Returns a new `RcTester` that returns `true` if either test passes.
1363    /// Borrows `&self`, so the original tester remains available.
1364    ///
1365    /// # Parameters
1366    ///
1367    /// * `next` - The tester to combine with
1368    ///
1369    /// # Return Value
1370    ///
1371    /// A new `RcTester` representing logical OR
1372    ///
1373    /// # Examples
1374    ///
1375    /// ```rust
1376    /// use prism3_function::{RcTester, Tester};
1377    ///
1378    /// let first = RcTester::new(|| false);
1379    /// let second = RcTester::new(|| true);
1380    /// let combined = first.or(&second);
1381    /// // first and second are still available
1382    /// ```
1383    pub fn or(&self, next: &RcTester) -> RcTester {
1384        let first = Rc::clone(&self.func);
1385        let second = Rc::clone(&next.func);
1386        RcTester {
1387            func: Rc::new(move || first() || second()),
1388        }
1389    }
1390
1391    /// Negates the result of this tester
1392    ///
1393    /// Returns a new `RcTester` that returns the opposite value of the
1394    /// original test result. Borrows `&self`, so the original tester remains
1395    /// available.
1396    ///
1397    /// # Return Value
1398    ///
1399    /// A new `RcTester` representing logical NOT
1400    ///
1401    /// # Examples
1402    ///
1403    /// ```rust
1404    /// use prism3_function::{RcTester, Tester};
1405    ///
1406    /// let original = RcTester::new(|| true);
1407    /// let negated = original.not();
1408    /// // original is still available
1409    /// ```
1410    #[allow(clippy::should_implement_trait)]
1411    pub fn not(&self) -> RcTester {
1412        let func = Rc::clone(&self.func);
1413        RcTester {
1414            func: Rc::new(move || !func()),
1415        }
1416    }
1417
1418    /// Combines this tester with another tester using logical NAND
1419    ///
1420    /// Returns a new `RcTester` that returns `true` unless both tests pass.
1421    /// Borrows `&self`, so the original tester remains available.
1422    ///
1423    /// # Parameters
1424    ///
1425    /// * `next` - The tester to combine with
1426    ///
1427    /// # Return Value
1428    ///
1429    /// A new `RcTester` representing logical NAND
1430    ///
1431    /// # Examples
1432    ///
1433    /// ```rust
1434    /// use prism3_function::{RcTester, Tester};
1435    ///
1436    /// let first = RcTester::new(|| true);
1437    /// let second = RcTester::new(|| true);
1438    /// let nand = first.nand(&second);
1439    ///
1440    /// // 两个都为 true 时返回 false
1441    /// assert!(!nand.test());
1442    ///
1443    /// // first 和 second 仍然可用
1444    /// assert!(first.test());
1445    /// assert!(second.test());
1446    /// ```
1447    pub fn nand(&self, next: &RcTester) -> RcTester {
1448        let first = Rc::clone(&self.func);
1449        let second = Rc::clone(&next.func);
1450        RcTester {
1451            func: Rc::new(move || !(first() && second())),
1452        }
1453    }
1454
1455    /// Combines this tester with another tester using logical XOR
1456    ///
1457    /// Returns a new `RcTester` that returns `true` if exactly one test
1458    /// passes. Borrows `&self`, so the original tester remains available.
1459    ///
1460    /// # Parameters
1461    ///
1462    /// * `next` - The tester to combine with
1463    ///
1464    /// # Return Value
1465    ///
1466    /// A new `RcTester` representing logical XOR
1467    ///
1468    /// # Examples
1469    ///
1470    /// ```rust
1471    /// use prism3_function::{RcTester, Tester};
1472    ///
1473    /// let first = RcTester::new(|| true);
1474    /// let second = RcTester::new(|| false);
1475    /// let xor = first.xor(&second);
1476    ///
1477    /// // 一个 true 一个 false 时返回 true
1478    /// assert!(xor.test());
1479    ///
1480    /// // first 和 second 仍然可用
1481    /// assert!(first.test());
1482    /// assert!(!second.test());
1483    /// ```
1484    pub fn xor(&self, next: &RcTester) -> RcTester {
1485        let first = Rc::clone(&self.func);
1486        let second = Rc::clone(&next.func);
1487        RcTester {
1488            func: Rc::new(move || first() ^ second()),
1489        }
1490    }
1491
1492    /// Combines this tester with another tester using logical NOR
1493    ///
1494    /// Returns a new `RcTester` that returns `true` only when both tests
1495    /// fail. Borrows `&self`, so the original tester remains available.
1496    ///
1497    /// # Parameters
1498    ///
1499    /// * `next` - The tester to combine with
1500    ///
1501    /// # Return Value
1502    ///
1503    /// A new `RcTester` representing logical NOR
1504    ///
1505    /// # Examples
1506    ///
1507    /// ```rust
1508    /// use prism3_function::{RcTester, Tester};
1509    ///
1510    /// let first = RcTester::new(|| false);
1511    /// let second = RcTester::new(|| false);
1512    /// let nor = first.nor(&second);
1513    ///
1514    /// // 两个都为 false 时返回 true
1515    /// assert!(nor.test());
1516    ///
1517    /// // first 和 second 仍然可用
1518    /// assert!(!first.test());
1519    /// assert!(!second.test());
1520    /// ```
1521    pub fn nor(&self, next: &RcTester) -> RcTester {
1522        let first = Rc::clone(&self.func);
1523        let second = Rc::clone(&next.func);
1524        RcTester {
1525            func: Rc::new(move || !(first() || second())),
1526        }
1527    }
1528}
1529
1530impl Tester for RcTester {
1531    fn test(&self) -> bool {
1532        (self.func)()
1533    }
1534
1535    fn into_box(self) -> BoxTester {
1536        let func = self.func;
1537        BoxTester {
1538            func: Box::new(move || func()),
1539        }
1540    }
1541
1542    fn into_rc(self) -> RcTester {
1543        self
1544    }
1545
1546    fn into_arc(self) -> ArcTester {
1547        // Note: RcTester is not Send, so this conversion is impossible.
1548        // Users should create ArcTester directly.
1549        panic!(
1550            "Cannot convert RcTester to ArcTester. Create ArcTester \
1551                directly with ArcTester::new()"
1552        )
1553    }
1554}
1555
1556impl Clone for RcTester {
1557    /// Creates a clone of this `RcTester`.
1558    ///
1559    /// The cloned instance shares the same underlying function with
1560    /// the original, allowing multiple references to the same test
1561    /// logic.
1562    fn clone(&self) -> Self {
1563        Self {
1564            func: Rc::clone(&self.func),
1565        }
1566    }
1567}
1568
1569// ============================================================================
1570// Tester Implementation for Closures
1571// ============================================================================
1572
1573impl<F> Tester for F
1574where
1575    F: Fn() -> bool,
1576{
1577    fn test(&self) -> bool {
1578        self()
1579    }
1580
1581    fn into_box(self) -> BoxTester
1582    where
1583        Self: Sized + 'static,
1584    {
1585        BoxTester::new(self)
1586    }
1587
1588    fn into_rc(self) -> RcTester
1589    where
1590        Self: Sized + 'static,
1591    {
1592        RcTester::new(self)
1593    }
1594
1595    fn into_arc(self) -> ArcTester
1596    where
1597        Self: Sized + Send + Sync + 'static,
1598    {
1599        ArcTester::new(self)
1600    }
1601}
1602
1603// ============================================================================
1604// Extension Trait for Convenient Closure Conversion
1605// ============================================================================
1606
1607/// Extension trait providing logical composition methods for closures
1608///
1609/// This trait is automatically implemented for all closures and function
1610/// pointers that match `Fn() -> bool`, enabling method chaining starting
1611/// from a closure.
1612///
1613/// # Examples
1614///
1615/// ```rust
1616/// use prism3_function::{FnTesterOps, Tester};
1617///
1618/// let is_ready = || true;
1619/// let is_available = || true;
1620///
1621/// // Combine testers using extension methods
1622/// let combined = is_ready.and(is_available);
1623/// assert!(combined.test());
1624/// ```
1625///
1626/// # Author
1627///
1628/// Hu Haixing
1629pub trait FnTesterOps: Sized + Fn() -> bool + 'static {
1630    /// Returns a tester that represents the logical AND of this tester
1631    /// and another
1632    ///
1633    /// # Parameters
1634    ///
1635    /// * `other` - The other tester to combine with. **Note: This parameter
1636    ///   is passed by value and will transfer ownership.** If you need to
1637    ///   preserve the original tester, clone it first (if it implements
1638    ///   `Clone`). Can be:
1639    ///   - Another closure
1640    ///   - A function pointer
1641    ///   - A `BoxTester`, `RcTester`, or `ArcTester`
1642    ///
1643    /// # Return Value
1644    ///
1645    /// A `BoxTester` representing the logical AND
1646    ///
1647    /// # Examples
1648    ///
1649    /// ```rust
1650    /// use prism3_function::{FnTesterOps, Tester};
1651    ///
1652    /// let is_ready = || true;
1653    /// let is_available = || true;
1654    ///
1655    /// let combined = is_ready.and(is_available);
1656    /// assert!(combined.test());
1657    /// ```
1658    fn and<T>(self, other: T) -> BoxTester
1659    where
1660        T: Tester + 'static,
1661    {
1662        BoxTester::new(move || self.test() && other.test())
1663    }
1664
1665    /// Returns a tester that represents the logical OR of this tester
1666    /// and another
1667    ///
1668    /// # Parameters
1669    ///
1670    /// * `other` - The other tester to combine with. **Note: This parameter
1671    ///   is passed by value and will transfer ownership.** If you need to
1672    ///   preserve the original tester, clone it first (if it implements
1673    ///   `Clone`). Can be:
1674    ///   - Another closure
1675    ///   - A function pointer
1676    ///   - A `BoxTester`, `RcTester`, or `ArcTester`
1677    ///   - Any type implementing `Tester`
1678    ///
1679    /// # Return Value
1680    ///
1681    /// A `BoxTester` representing the logical OR
1682    ///
1683    /// # Examples
1684    ///
1685    /// ```rust
1686    /// use prism3_function::{FnTesterOps, Tester};
1687    ///
1688    /// let is_ready = || false;
1689    /// let is_fallback = || true;
1690    ///
1691    /// let combined = is_ready.or(is_fallback);
1692    /// assert!(combined.test());
1693    /// ```
1694    fn or<T>(self, other: T) -> BoxTester
1695    where
1696        T: Tester + 'static,
1697    {
1698        BoxTester::new(move || self.test() || other.test())
1699    }
1700
1701    /// Returns a tester that represents the logical negation of this tester
1702    ///
1703    /// # Return Value
1704    ///
1705    /// A `BoxTester` representing the logical negation
1706    ///
1707    /// # Examples
1708    ///
1709    /// ```rust
1710    /// use prism3_function::{FnTesterOps, Tester};
1711    ///
1712    /// let is_ready = || false;
1713    /// let not_ready = is_ready.not();
1714    /// assert!(not_ready.test());
1715    /// ```
1716    fn not(self) -> BoxTester {
1717        BoxTester::new(move || !self.test())
1718    }
1719
1720    /// Returns a tester that represents the logical NAND (NOT AND) of this
1721    /// tester and another
1722    ///
1723    /// NAND returns `true` unless both testers are `true`.
1724    /// Equivalent to `!(self AND other)`.
1725    ///
1726    /// # Parameters
1727    ///
1728    /// * `other` - The other tester to combine with. **Note: This parameter
1729    ///   is passed by value and will transfer ownership.** If you need to
1730    ///   preserve the original tester, clone it first (if it implements
1731    ///   `Clone`). Accepts closures, function pointers, or any
1732    ///   `Tester` implementation.
1733    ///
1734    /// # Return Value
1735    ///
1736    /// A `BoxTester` representing the logical NAND
1737    ///
1738    /// # Examples
1739    ///
1740    /// ```rust
1741    /// use prism3_function::{FnTesterOps, Tester};
1742    ///
1743    /// let is_ready = || true;
1744    /// let is_available = || true;
1745    ///
1746    /// let nand = is_ready.nand(is_available);
1747    /// assert!(!nand.test());  // !(true && true) = false
1748    /// ```
1749    fn nand<T>(self, other: T) -> BoxTester
1750    where
1751        T: Tester + 'static,
1752    {
1753        BoxTester::new(move || !(self.test() && other.test()))
1754    }
1755
1756    /// Returns a tester that represents the logical XOR (exclusive OR) of
1757    /// this tester and another
1758    ///
1759    /// XOR returns `true` if exactly one of the testers is `true`.
1760    ///
1761    /// # Parameters
1762    ///
1763    /// * `other` - The other tester to combine with. **Note: This parameter
1764    ///   is passed by value and will transfer ownership.** If you need to
1765    ///   preserve the original tester, clone it first (if it implements
1766    ///   `Clone`). Accepts closures, function pointers, or any
1767    ///   `Tester` implementation.
1768    ///
1769    /// # Return Value
1770    ///
1771    /// A `BoxTester` representing the logical XOR
1772    ///
1773    /// # Examples
1774    ///
1775    /// ```rust
1776    /// use prism3_function::{FnTesterOps, Tester};
1777    ///
1778    /// let is_ready = || true;
1779    /// let is_available = || false;
1780    ///
1781    /// let xor = is_ready.xor(is_available);
1782    /// assert!(xor.test());  // true ^ false = true
1783    /// ```
1784    fn xor<T>(self, other: T) -> BoxTester
1785    where
1786        T: Tester + 'static,
1787    {
1788        BoxTester::new(move || self.test() ^ other.test())
1789    }
1790
1791    /// Returns a tester that represents the logical NOR (NOT OR) of this
1792    /// tester and another
1793    ///
1794    /// NOR returns `true` only when both testers are `false`. Equivalent
1795    /// to `!(self OR other)`.
1796    ///
1797    /// # Parameters
1798    ///
1799    /// * `other` - The other tester to combine with. **Note: This parameter
1800    ///   is passed by value and will transfer ownership.** If you need to
1801    ///   preserve the original tester, clone it first (if it implements
1802    ///   `Clone`). Accepts closures, function pointers, or any
1803    ///   `Tester` implementation.
1804    ///
1805    /// # Return Value
1806    ///
1807    /// A `BoxTester` representing the logical NOR
1808    ///
1809    /// # Examples
1810    ///
1811    /// ```rust
1812    /// use prism3_function::{FnTesterOps, Tester};
1813    ///
1814    /// let is_ready = || false;
1815    /// let is_available = || false;
1816    ///
1817    /// let nor = is_ready.nor(is_available);
1818    /// assert!(nor.test());  // !(false || false) = true
1819    /// ```
1820    fn nor<T>(self, other: T) -> BoxTester
1821    where
1822        T: Tester + 'static,
1823    {
1824        BoxTester::new(move || !(self.test() || other.test()))
1825    }
1826}
1827
1828// Blanket implementation for all closures
1829impl<F> FnTesterOps for F where F: Fn() -> bool + 'static {}