pub struct BoxTester { /* private fields */ }Expand description
Single ownership Tester implemented using Box
BoxTester wraps a closure in Box<dyn Fn() -> bool>, providing single
ownership semantics with no additional allocation overhead beyond the
initial boxing.
§Characteristics
- Single ownership: Cannot be cloned
 - Zero overhead: Single heap allocation
 - Consuming combination: 
and()/or()/not()consumeself - Type flexibility: Accepts any 
Testerimplementation 
§Use Cases
- One-time testing scenarios
 - Builder patterns requiring ownership transfer
 - Simple state checking without sharing
 - Chained calls with ownership transfer
 
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
// State managed externally
let count = Arc::new(AtomicUsize::new(0));
let count_clone = Arc::clone(&count);
let tester = BoxTester::new(move || {
    count_clone.load(Ordering::Relaxed) < 3
});
assert!(tester.test());
count.fetch_add(1, Ordering::Relaxed);
assert!(tester.test());
count.fetch_add(1, Ordering::Relaxed);
assert!(tester.test());
count.fetch_add(1, Ordering::Relaxed);
assert!(!tester.test());
// Logical combination
let combined = BoxTester::new(|| true)
    .and(|| false)
    .or(|| true);
assert!(combined.test());§Author
Hu Haixing
Implementations§
Source§impl BoxTester
 
impl BoxTester
Sourcepub fn and<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
 
pub fn and<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
Combines this tester with another tester using logical AND
Returns a new BoxTester that returns true only when both tests
pass. Short-circuit evaluation: if the first test fails, the second
will not be executed.
§Type Parameters
T- Type implementingTester
§Parameters
next- The tester to combine with
§Return Value
A new BoxTester representing logical AND
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
// Simulate service status
let request_count = Arc::new(AtomicUsize::new(0));
let is_available = Arc::new(AtomicBool::new(true));
let max_requests = 1000;
let count_clone = Arc::clone(&request_count);
let available_clone = Arc::clone(&is_available);
// Service available and request count not exceeded
let service_ok = BoxTester::new(move || {
    available_clone.load(Ordering::Relaxed)
})
.and(move || {
    count_clone.load(Ordering::Relaxed) < max_requests
});
// Initial state: available and request count 0
assert!(service_ok.test());
// Simulate request increase
request_count.store(500, Ordering::Relaxed);
assert!(service_ok.test());
// Request count exceeded
request_count.store(1500, Ordering::Relaxed);
assert!(!service_ok.test());
// Service unavailable
is_available.store(false, Ordering::Relaxed);
assert!(!service_ok.test());Sourcepub fn or<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
 
pub fn or<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
Combines this tester with another tester using logical OR
Returns a new BoxTester that returns true if either test passes.
Short-circuit evaluation: if the first test passes, the second will
not be executed.
§Type Parameters
T- Type implementingTester
§Parameters
next- The tester to combine with
§Return Value
A new BoxTester representing logical OR
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, AtomicBool, Ordering}};
// Simulate service status
let request_count = Arc::new(AtomicUsize::new(0));
let is_healthy = Arc::new(AtomicBool::new(true));
let max_requests = 100;
let count_clone = Arc::clone(&request_count);
let health_clone = Arc::clone(&is_healthy);
// Service healthy or low request count
let can_serve = BoxTester::new(move || {
    health_clone.load(Ordering::Relaxed)
})
.or(move || {
    count_clone.load(Ordering::Relaxed) < max_requests
});
// Initial state: healthy and request count 0
assert!(can_serve.test());
// Request count increased but within limit
request_count.store(50, Ordering::Relaxed);
assert!(can_serve.test());
// Request count exceeded but service healthy
request_count.store(150, Ordering::Relaxed);
assert!(can_serve.test()); // still healthy
// Service unhealthy but low request count
is_healthy.store(false, Ordering::Relaxed);
request_count.store(50, Ordering::Relaxed);
assert!(can_serve.test()); // low request count
// Unhealthy and high request count
request_count.store(150, Ordering::Relaxed);
assert!(!can_serve.test());Sourcepub fn not(self) -> BoxTester
 
pub fn not(self) -> BoxTester
Negates the result of this tester
Returns a new BoxTester that returns the opposite value of the
original test result.
§Return Value
A new BoxTester representing logical NOT
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
// Simulate resource usage
let memory_usage = Arc::new(AtomicUsize::new(0));
let max_memory = 1024; // MB
let memory_clone = Arc::clone(&memory_usage);
// Memory usage not exceeded
let memory_ok = BoxTester::new(move || {
    memory_clone.load(Ordering::Relaxed) <= max_memory
});
// Initial state: normal memory usage
memory_usage.store(512, Ordering::Relaxed);
assert!(memory_ok.test());
// Memory usage exceeded (negated)
let memory_critical = memory_ok.not();
assert!(!memory_critical.test());
// Memory usage exceeded
memory_usage.store(2048, Ordering::Relaxed);
assert!(memory_critical.test());Sourcepub fn nand<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
 
pub fn nand<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
Combines this tester with another tester using logical NAND
Returns a new BoxTester that returns true unless both tests pass.
Equivalent to !(self AND other).
§Type Parameters
T- Type implementingTester
§Parameters
next- The tester to combine with
§Return Value
A new BoxTester representing logical NAND
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
let flag1 = Arc::new(AtomicBool::new(true));
let flag2 = Arc::new(AtomicBool::new(true));
let flag1_clone = Arc::clone(&flag1);
let flag2_clone = Arc::clone(&flag2);
let nand = BoxTester::new(move || {
    flag1_clone.load(Ordering::Relaxed)
})
.nand(move || {
    flag2_clone.load(Ordering::Relaxed)
});
// Both true returns false
assert!(!nand.test());
// At least one false returns true
flag1.store(false, Ordering::Relaxed);
assert!(nand.test());Sourcepub fn xor<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
 
pub fn xor<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
Combines this tester with another tester using logical XOR
Returns a new BoxTester that returns true if exactly one test
passes.
§Type Parameters
T- Type implementingTester
§Parameters
next- The tester to combine with
§Return Value
A new BoxTester representing logical XOR
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
let flag1 = Arc::new(AtomicBool::new(true));
let flag2 = Arc::new(AtomicBool::new(false));
let flag1_clone1 = Arc::clone(&flag1);
let flag2_clone1 = Arc::clone(&flag2);
let xor = BoxTester::new(move || {
    flag1_clone1.load(Ordering::Relaxed)
})
.xor(move || {
    flag2_clone1.load(Ordering::Relaxed)
});
// One true one false returns true
assert!(xor.test());
// Both true returns false
flag2.store(true, Ordering::Relaxed);
assert!(!xor.test());
// Both false returns false
flag1.store(false, Ordering::Relaxed);
flag2.store(false, Ordering::Relaxed);
assert!(!xor.test());Sourcepub fn nor<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
 
pub fn nor<T>(self, next: T) -> BoxTesterwhere
    T: Tester + 'static,
Combines this tester with another tester using logical NOR
Returns a new BoxTester that returns true only when both tests
fail. Equivalent to !(self OR other).
§Type Parameters
T- Type implementingTester
§Parameters
next- The tester to combine with
§Return Value
A new BoxTester representing logical NOR
§Examples
use prism3_function::{BoxTester, Tester};
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
let flag1 = Arc::new(AtomicBool::new(false));
let flag2 = Arc::new(AtomicBool::new(false));
let flag1_clone = Arc::clone(&flag1);
let flag2_clone = Arc::clone(&flag2);
let nor = BoxTester::new(move || {
    flag1_clone.load(Ordering::Relaxed)
})
.nor(move || {
    flag2_clone.load(Ordering::Relaxed)
});
// Both false returns true
assert!(nor.test());
// At least one true returns false
flag1.store(true, Ordering::Relaxed);
assert!(!nor.test());