Prism3 Function
Comprehensive functional programming abstractions for Rust, providing Java-style functional interfaces with Rust's ownership models.
Overview
This crate provides a complete set of functional programming abstractions inspired by Java's functional interfaces, adapted to Rust's ownership system. It offers multiple implementations for each abstraction (Box/Arc/Rc) to cover various use cases from simple single-threaded scenarios to complex multi-threaded applications.
Key Features
- Complete Functional Interface Suite: Predicate, Consumer, Supplier, ReadonlySupplier, Transformer, Mutator, BiConsumer, BiPredicate, BiTransformer, Comparator, and Tester
 - Multiple Ownership Models: Box-based single ownership, Arc-based thread-safe sharing, and Rc-based single-threaded sharing
 - Flexible API Design: Trait-based unified interface with concrete implementations optimized for different scenarios
 - Method Chaining: All types support fluent API and functional composition
 - Thread-Safety Options: Choose between thread-safe (Arc) and efficient single-threaded (Rc) implementations
 - Lock-Free Concurrency: ReadonlySupplier provides lock-free concurrent access for stateless scenarios
 - Zero-Cost Abstractions: Efficient implementations with minimal runtime overhead
 
Core Types
Predicate
Tests whether a value satisfies a condition, returning bool. Similar to Java's Predicate<T> interface.
Core Function
test(&self, value: &T) -> bool- Tests if the value satisfies the predicate condition- Corresponds to 
Fn(&T) -> boolclosure 
Implementations
BoxPredicate<T>: Single ownership, non-cloneableArcPredicate<T>: Thread-safe shared ownership, cloneableRcPredicate<T>: Single-threaded shared ownership, cloneable
Convenience Methods
- Logical composition: 
and,or,not,xor,nand,nor - Type-preserving method chaining (each returns the same concrete type)
 - Extension trait 
FnPredicateOpsfor closures - provides composition methods that returnBoxPredicate 
⚠️ Important: Ownership Transfer in Logical Operations
All logical composition methods (and, or, xor, nand, nor) accept the other parameter by value, which means:
- Ownership is transferred: The 
otherpredicate is consumed and becomes unavailable after the operation - To preserve the original: You must explicitly 
clone()it first (only works forArcPredicateandRcPredicate) BoxPredicatecannot be cloned: Once used in a composition, it's consumed
use ;
// ArcPredicate and RcPredicate can be cloned
let is_even = new;
let is_positive = new;
// Option 1: Clone to preserve the original
let combined = is_even.and;
// is_positive is still usable because we cloned it
assert!;
// Option 2: Use &self methods (for Rc/Arc only)
let is_even_rc = new;
let is_positive_rc = new;
let combined_rc = is_even_rc.and;
// Both predicates remain usable
assert!;
assert!;
// BoxPredicate: Cannot be cloned, will be consumed
let box_pred = new;
let combined_box = box_pred.and;
// box_pred is no longer available here
Example
use ;
// Create predicates with logical composition
let is_even = new;
let is_positive = new;
// Clone to preserve the original predicate
let is_even_and_positive = is_even.and;
assert!;
assert!;
// is_positive is still usable
assert!;
// Use with closures - extension trait automatically provides composition
let numbers = vec!;
let result:  = numbers
    .into_iter
    .filter
    .collect;
Consumer
Accepts a single input parameter and performs operations without returning a result. Similar to Java's Consumer<T>.
Core Function
accept(&mut self, value: &T)- Performs an operation on the value reference- Corresponds to 
FnMut(&T)closure 
Implementations
BoxConsumer<T>: Single ownership, usesFnMut(&T)ArcConsumer<T>: Thread-safe withArc<Mutex<>>, cloneableRcConsumer<T>: Single-threaded withRc<RefCell<>>, cloneableBoxConsumerOnce<T>: One-time use withFnOnce(&T)
Convenience Methods
and_then- Chains consumers sequentiallywhen- Conditional execution with predicate- Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnConsumerOpsfor closures 
Related Types
ReadonlyConsumer- For pure observation without modifying consumer state
⚠️ Important: Ownership Transfer in Composition Methods
All composition methods (and_then, when, or_else) accept their parameters by value, which means:
- Ownership is transferred: The parameter (consumer or predicate) is consumed and becomes unavailable after the operation
 - To preserve the original: You must explicitly 
clone()it first (only works forArcConsumerandRcConsumer) - BoxConsumer cannot be cloned: Once used in a composition, it's consumed and no longer available
 
Examples
Basic Usage
use ;
// Create a consumer for observation (not modification)
let mut consumer = new;
let value = 10;
consumer.accept_once;
// value is unchanged
Chaining with and_then
use ;
use ;
let log = new;
let log1 = log.clone;
let log2 = log.clone;
// Chain multiple consumers
let mut consumer = new
.and_then;
consumer.accept_once;
assert_eq!;
Conditional Execution with when
use ;
use ;
let log = new;
let log_clone = log.clone;
// Only execute consumer when predicate is true
let mut consumer = new
.when;  // Only log positive numbers
consumer.accept_once;   // Logged
consumer.accept_once;   // Not logged
assert_eq!;
If-Then-Else with or_else
use ;
use ;
let log = new;
let log1 = log.clone;
let log2 = log.clone;
// Execute different consumers based on condition
let mut consumer = new
.when
.or_else;
consumer.accept_once;   // "Positive: 10"
consumer.accept_once;   // "Non-positive: -5"
assert_eq!;
Mutator
Modifies values in-place by accepting mutable references. Similar to Java's UnaryOperator<T> but with in-place modification.
Core Function
mutate(&mut self, value: &mut T)- Modifies the value in-place- Corresponds to 
FnMut(&mut T)closure 
Implementations
BoxMutator<T>: Single ownership, usesFnMut(&mut T)ArcMutator<T>: Thread-safe withArc<Mutex<>>, cloneableRcMutator<T>: Single-threaded withRc<RefCell<>>, cloneableBoxMutatorOnce<T>: One-time use withFnOnce(&mut T)
Convenience Methods
and_then- Chains mutators sequentiallywhen- Creates conditional mutator (if-then pattern)or_else- Adds else branch to conditional mutator (if-then-else pattern)- Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnMutatorOpsfor closures 
Key Difference from Consumer
- Consumer: Accepts 
&T(reads values, doesn't modify input) - Mutator: Accepts 
&mut T(modifies values in-place) 
Example
use ;
// Create a mutator that modifies values
let mut mutator = new
    .and_then;
let mut value = 10;
mutator.mutate;
assert_eq!; // (10 * 2) + 1
// Conditional mutator with if-then-else logic
let mut conditional = new
    .when
    .or_else;
let mut positive = 5;
conditional.mutate;
assert_eq!; // 5 * 2
let mut negative = -5;
conditional.mutate;
assert_eq!; // -5 - 1
Supplier
Generates values lazily without input parameters. Similar to Java's Supplier<T>.
Core Function
get(&mut self) -> T- Generates and returns a value- Corresponds to 
FnMut() -> Tclosure 
Implementations
BoxSupplier<T>: Single ownership, usesFnMut() -> TArcSupplier<T>: Thread-safe withArc<Mutex<>>, cloneableRcSupplier<T>: Single-threaded withRc<RefCell<>>, cloneableBoxSupplierOnce<T>: One-time use withFnOnce() -> T
Convenience Methods
map- Transforms supplier outputfilter- Filters supplier output with predicateflat_map- Chains suppliers- Factory methods: 
constant,counter - Type conversions: 
into_box,into_arc,into_rc 
Example
use ;
// Create a counter supplier
let mut counter = ;
assert_eq!;
assert_eq!;
assert_eq!;
// Method chaining with map
let mut pipeline = new
    .map
    .map;
assert_eq!;
ReadonlySupplier
Generates values lazily without input parameters and without modifying its own state. Unlike Supplier<T>, it uses &self instead of &mut self, enabling usage in read-only contexts and lock-free concurrent access.
Core Function
get(&self) -> T- Generates and returns a value (note:&self, not&mut self)- Corresponds to 
Fn() -> Tclosure 
Key Differences from Supplier
| Aspect | Supplier | ReadonlySupplier | 
|---|---|---|
| self signature | &mut self | 
&self | 
| Closure type | FnMut() -> T | 
Fn() -> T | 
| Can modify state | Yes | No | 
| Arc implementation | Arc<Mutex<FnMut>> | 
Arc<Fn> (lock-free!) | 
| Use cases | Counter, generator | Factory, constant, high concurrency | 
Implementations
BoxReadonlySupplier<T>: Single ownership, zero overheadArcReadonlySupplier<T>: Lock-free thread-safe sharing (noMutexneeded!)RcReadonlySupplier<T>: Single-threaded sharing, lightweight
Convenience Methods
map- Transforms supplier outputfilter- Filters supplier output with predicatezip- Combines two suppliers- Factory methods: 
constant - Type conversions: 
into_box,into_arc,into_rc 
Use Cases
1. Calling in &self Methods
use ;
2. High-Concurrency Lock-Free Access
use ;
use thread;
let factory = new;
let handles:  = 
    .map
    .collect;
for h in handles 
3. Fixed Factories
use ;
let config_factory = new;
assert_eq!;
assert_eq!;
Performance Comparison
For stateless scenarios in multi-threaded environments:
ArcSupplier<T>: RequiresMutex, lock contention on everyget()callArcReadonlySupplier<T>: Lock-free, can callget()concurrently without contention
Benchmark results show ArcReadonlySupplier can be 10x faster than ArcSupplier in high-concurrency scenarios.
Transformer<T, R>
Transforms values from type T to type R by consuming input. Similar to Java's Function<T, R>.
Core Function
transform(&self, input: T) -> R- Transforms input value to output value (consumes input)- Corresponds to 
Fn(T) -> Rclosure 
Implementations
BoxTransformer<T, R>: Reusable, single ownership (Fn)ArcTransformer<T, R>: Thread-safe, cloneable (Arc)RcTransformer<T, R>: Single-threaded, cloneable (Rc)BoxTransformerOnce<T, R>: One-time use (FnOnce)
Convenience Methods
and_then- Composes transformers sequentially (f.and_then(g) = g(f(x)))compose- Composes transformers in reverse order (f.compose(g) = f(g(x)))when- Creates conditional transformer with predicate- Factory methods: 
identity,constant - Type conversions: 
into_box,into_arc,into_rc,into_fn - Extension trait 
FnTransformerOpsfor closures 
Related Types
UnaryOperator<T>- Type alias forTransformer<T, T>
⚠️ Important: Ownership Transfer in Composition Methods
All composition methods (and_then, compose, when, or_else) accept their parameters by value, which means:
- Ownership is transferred: The parameter (transformer or predicate) is consumed and becomes unavailable after the operation
 - To preserve the original: You must explicitly 
clone()it first (only works forArcTransformerandRcTransformer) - BoxTransformer cannot be cloned: Once used in a composition, it's consumed and no longer available
 
Examples
Basic Usage and and_then Chaining
use ;
// Chain transformers for data transformation
let parse_and_double = new
    .and_then
    .and_then;
assert_eq!;
assert_eq!;
Conditional Transformation with when
use ;
// Apply transformation only when predicate is true
let double_if_positive = new
    .when;
assert_eq!;
assert_eq!;
If-Then-Else with or_else
use ;
// Different transformations based on condition
let transform = new
    .when
    .or_else;
assert_eq!;
assert_eq!;
BiConsumer<T, U>
Accepts two input parameters and performs operations without returning a result. Similar to Java's BiConsumer<T, U>.
Core Function
accept(&mut self, first: &T, second: &U)- Performs an operation on two value references- Corresponds to 
FnMut(&T, &U)closure 
Implementations
BoxBiConsumer<T, U>: Single ownershipArcBiConsumer<T, U>: Thread-safe, cloneableRcBiConsumer<T, U>: Single-threaded, cloneableBoxBiConsumerOnce<T, U>: One-time use
Convenience Methods
and_then- Chains bi-consumers sequentiallywhen- Conditional execution with bi-predicate- Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnBiConsumerOpsfor closures 
Related Types
ReadonlyBiConsumer- For pure observation without modifying consumer state
⚠️ Important: Ownership Transfer in Composition Methods
All composition methods (and_then, when, or_else) accept their parameters by value, which means:
- Ownership is transferred: The parameter (bi-consumer or bi-predicate) is consumed and becomes unavailable after the operation
 - To preserve the original: You must explicitly 
clone()it first (only works forArcBiConsumerandRcBiConsumer) - BoxBiConsumer cannot be cloned: Once used in a composition, it's consumed and no longer available
 
Examples
Basic Usage
use ;
// Create a bi-consumer for pair operations
let mut bi_consumer = new;
bi_consumer.accept_once;
Chaining with and_then
use ;
use ;
let log = new;
let log1 = log.clone;
let log2 = log.clone;
// Chain multiple bi-consumers
let mut bi_consumer = new
.and_then;
bi_consumer.accept_once;
assert_eq!;
// log contains: ["Sum: 7", "Product: 12"]
Conditional Execution with when
use ;
use ;
let log = new;
let log_clone = log.clone;
// Only execute when both values are positive
let mut bi_consumer = new
.when;
bi_consumer.accept_once;   // Logged
bi_consumer.accept_once;  // Not logged
assert_eq!;
If-Then-Else with or_else
use ;
use ;
let log = new;
let log1 = log.clone;
let log2 = log.clone;
// Different operations based on condition
let mut bi_consumer = new
.when
.or_else;
bi_consumer.accept_once;   // "Both positive: 3 + 4 = 7"
bi_consumer.accept_once;  // "Has negative: -1 * 4 = -4"
assert_eq!;
BiPredicate<T, U>
Tests whether two values satisfy a condition, returning bool. Similar to Java's BiPredicate<T, U>.
Core Function
test(&self, first: &T, second: &U) -> bool- Tests if two values satisfy the predicate condition- Corresponds to 
Fn(&T, &U) -> boolclosure 
Implementations
BoxBiPredicate<T, U>: Single ownership, non-cloneableArcBiPredicate<T, U>: Thread-safe, cloneableRcBiPredicate<T, U>: Single-threaded, cloneable
Convenience Methods
- Logical composition: 
and,or,not,xor,nand,nor - Type-preserving method chaining
 - Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnBiPredicateOpsfor closures 
⚠️ Important: Ownership Transfer in Logical Operations
All logical composition methods (and, or, xor, nand, nor) accept the other parameter by value, which means:
- Ownership is transferred: The 
otherbi-predicate is consumed and becomes unavailable after the operation - To preserve the original: You must explicitly 
clone()it first (only works forArcBiPredicateandRcBiPredicate) BoxBiPredicatecannot be cloned: Once used in a composition, it's consumed
use ;
// ArcBiPredicate and RcBiPredicate can be cloned
let is_sum_positive = new;
let first_larger = new;
// Clone to preserve the original
let combined = is_sum_positive.and;
// first_larger is still usable because we cloned it
assert!;
// BoxBiPredicate: Cannot be cloned, will be consumed
let box_pred = new;
let combined_box = box_pred.and;
// box_pred is no longer available here
Example
use ;
// Create bi-predicates with logical composition
let is_sum_positive = new;
let first_larger = new;
// Clone to preserve the original predicate
let combined = is_sum_positive.and;
assert!;
assert!;
// first_larger is still usable
assert!;
BiTransformer<T, U, R>
Transforms two input values to produce a result value. Similar to Java's BiFunction<T, U, R>.
Core Function
transform(&self, first: T, second: U) -> R- Transforms two input values to output value (consumes inputs)- Corresponds to 
Fn(T, U) -> Rclosure 
Implementations
BoxBiTransformer<T, U, R>: Reusable, single ownership (Fn)ArcBiTransformer<T, U, R>: Thread-safe, cloneable (Arc)RcBiTransformer<T, U, R>: Single-threaded, cloneable (Rc)BoxBiTransformerOnce<T, U, R>: One-time use (FnOnce)
Convenience Methods
and_then- Composes bi-transformer with transformerwhen- Creates conditional bi-transformer with bi-predicate- Type conversions: 
into_box,into_arc,into_rc,into_fn - Extension trait 
FnBiTransformerOpsfor closures 
Related Types
BinaryOperator<T>- Type alias forBiTransformer<T, T, T>
⚠️ Important: Ownership Transfer in Composition Methods
All composition methods (and_then, when, or_else) accept their parameters by value, which means:
- Ownership is transferred: The parameter (transformer or bi-predicate) is consumed and becomes unavailable after the operation
 - To preserve the original: You must explicitly 
clone()it first (only works forArcBiTransformerandRcBiTransformer) - BoxBiTransformer cannot be cloned: Once used in a composition, it's consumed and no longer available
 
Examples
Basic Usage and and_then Chaining
use ;
// Create a bi-transformer for combining two values
let add = new;
assert_eq!;
// Chain with transformer for further processing
let add_and_double = new
    .and_then;
assert_eq!;
// Multiple chaining
let complex = new
    .and_then
    .and_then;
assert_eq!;
Conditional Transformation with when
use ;
// Only transform when both values are positive
let add_if_positive = new
    .when;
assert_eq!;
assert_eq!;
assert_eq!;
If-Then-Else with or_else
use ;
// Different transformations based on condition
let transform = new
    .when
    .or_else;
assert_eq!;
assert_eq!;
assert_eq!;
Comparator
Compares two values and returns an Ordering. Similar to Java's Comparator<T>.
Core Function
compare(&self, a: &T, b: &T) -> Ordering- Compares two values and returns ordering- Corresponds to 
Fn(&T, &T) -> Orderingclosure 
Implementations
BoxComparator<T>: Single ownershipArcComparator<T>: Thread-safe, cloneableRcComparator<T>: Single-threaded, cloneable
Convenience Methods
reversed- Reverses the comparison orderthen_comparing- Chains comparators (secondary sort key)- Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnComparatorOpsfor closures 
Example
use ;
use Ordering;
// Create a comparator
let cmp = new;
assert_eq!;
// Reverse the order
let reversed = cmp.reversed;
assert_eq!;
Tester
Tests whether a state or condition holds without accepting input parameters. Similar to Java's BooleanSupplier but with Rust's ownership semantics.
Core Function
test(&self) -> bool- Tests if a state or condition holds- Corresponds to 
Fn() -> boolclosure 
Implementations
BoxTester: Single ownership, non-cloneableArcTester: Thread-safe shared ownership, cloneableRcTester: Single-threaded shared ownership, cloneable
Convenience Methods
- Logical composition: 
and,or,not - Type conversions: 
into_box,into_arc,into_rc - Extension trait 
FnTesterOpsfor closures 
Key Design Philosophy
- Uses 
&self: Tester is only responsible for "judgment", not "state management" - State management is caller's responsibility: Tester only reads state, does not modify state
 - Repeatable calls: The same Tester can call 
test()multiple times - No TesterOnce: Very limited use cases, directly using closures is better
 
⚠️ Important: Ownership Transfer in Logical Operations
All logical composition methods (and, or, not) accept the other parameter by value, which means:
- Ownership is transferred: The 
othertester is consumed and becomes unavailable after the operation - To preserve the original: You must explicitly 
clone()it first (only works forArcTesterandRcTester) BoxTestercannot be cloned: Once used in a composition, it's consumed
use ;
// ArcTester and RcTester can be cloned
let is_ready = new;
let is_healthy = new;
// Clone to preserve the original
let combined = is_ready.and;
// is_healthy is still usable because we cloned it
assert!;
// BoxTester: Cannot be cloned, will be consumed
let box_tester = new;
let combined_box = box_tester.and;
// box_tester is no longer available here
Examples
Basic State Checking
use ;
use ;
// State managed externally
let count = new;
let count_clone = clone;
let tester = new;
assert!;  // true (0)
count.fetch_add;
assert!;  // true (1)
count.fetch_add;
assert!;  // true (2)
count.fetch_add;
assert!;  // true (3)
count.fetch_add;
assert!; // false (4)
Logical Combination
use ;
use ;
// 模拟系统状态 - 使用原子类型
let cpu_usage = new; // 45%
let memory_usage = new; // 60%
let disk_space = new; // 25% free
let network_connected = new;
let service_running = new;
// 创建各种条件检查器
let cpu_ok = new;
let memory_ok = new;
let disk_ok = new;
let network_ok = new;
let service_ok = new;
// 组合条件:系统健康检查
let system_healthy = cpu_ok
    .and
    .and
    .and
    .and;
// 组合条件:紧急状态检查(CPU或内存过高)
let emergency_state = new.or;
// 组合条件:服务可用性检查(网络和服务都正常)
let service_available = network_ok.and;
// 组合条件:资源充足检查(CPU、内存、磁盘都正常)
let resources_adequate = cpu_ok.and.and;
// 使用组合条件
assert!;
assert!;
assert!;
assert!;
// 复杂的逻辑组合:系统可以处理新请求的条件
let can_handle_requests = service_available
    .and
    .and;
assert!;
// 测试状态变化
cpu_usage.store;
assert!;
// 模拟CPU使用率过高
cpu_usage.store;
assert!;
Thread-Safe Sharing
use ;
use thread;
let shared = new;
let clone = shared.clone;
let handle = spawn;
assert!;
Condition Waiting
use ;
use ;
use ;
// Usage
let ready = new;
let ready_clone = clone;
let tester = new;
// Another thread sets the flag
let ready_clone2 = clone;
spawn;
// Wait for condition
if wait_until  else 
Installation
Add this to your Cargo.toml:
[]
 = "0.1.0"
Design Philosophy
This crate adopts the Trait + Multiple Implementations pattern, providing:
- Unified Interface: Each functional type has a trait defining core behavior
 - Specialized Implementations: Multiple concrete types optimized for different scenarios
 - Type Preservation: Composition methods return the same concrete type
 - Ownership Flexibility: Choose between single ownership, thread-safe sharing, or single-threaded sharing
 - Ergonomic API: Natural method chaining without explicit cloning
 
Comparison Table
| Type | Box (Single) | Arc (Thread-Safe) | Rc (Single-Thread) | 
|---|---|---|---|
| Predicate | BoxPredicate | ArcPredicate | RcPredicate | 
| Consumer | BoxConsumer | ArcConsumer | RcConsumer | 
| Mutator | BoxMutator | ArcMutator | RcMutator | 
| Supplier | BoxSupplier | ArcSupplier | RcSupplier | 
| Transformer | BoxTransformer | ArcTransformer | RcTransformer | 
| BiConsumer | BoxBiConsumer | ArcBiConsumer | RcBiConsumer | 
| BiPredicate | BoxBiPredicate | ArcBiPredicate | RcBiPredicate | 
| BiTransformer | BoxBiTransformer | ArcBiTransformer | RcBiTransformer | 
| Comparator | BoxComparator | ArcComparator | RcComparator | 
| Tester | BoxTester | ArcTester | RcTester | 
Legend
- Box: Single ownership, cannot be cloned, consumes self
 - Arc: Shared ownership, thread-safe, cloneable
 - Rc: Shared ownership, single-threaded, cloneable
 
Documentation
- Predicate Design | 中文
 - Consumer Design | 中文
 - Mutator Design | 中文
 - Supplier Design | 中文
 - Transformer Design | 中文
 - Tester Design | - 中文
 
Examples
The examples/ directory contains comprehensive demonstrations:
predicate_demo.rs: Predicate usage patternsconsumer_demo.rs: Consumer usage patternsmutator_demo.rs: Mutator usage patternsmutator_once_conditional_demo.rs: Conditional mutator patternssupplier_demo.rs: Supplier usage patternstransformer_demo.rs: Transformer usage patterns- And more...
 
Run examples with:
License
Licensed under Apache License, Version 2.0.
Author
Haixing Hu starfish.hu@gmail.com