pub struct RcStatefulConsumer<T> { /* private fields */ }Expand description
RcStatefulConsumer struct
Consumer implementation based on Rc<RefCell<dyn FnMut(&T)>> for
single-threaded shared ownership scenarios. This consumer provides the
benefits of shared ownership without the overhead of thread safety.
§Features
- Shared Ownership: Cloneable through
Rc, allowing multiple owners - Single-Threaded: Not thread-safe, cannot be sent across threads
- Interior Mutability: Uses
RefCellfor runtime borrowing checks - No Lock Overhead: More efficient than
ArcStatefulConsumerfor single-threaded use - Non-Consuming API:
and_thenborrows&self, original object remains usable
§Use Cases
Choose RcStatefulConsumer when:
- Need to share consumers within a single thread
- Thread safety is not needed
- Performance is important (avoid lock overhead)
- UI event handling in single-threaded frameworks
- Building complex single-threaded state machines
§Performance Considerations
RcStatefulConsumer performs better than ArcStatefulConsumer in single-threaded scenarios:
- Non-Atomic Counting: clone/drop is cheaper than
Arc - No Lock Overhead:
RefCelluses runtime checks, no locks - Better Cache Locality: No atomic operations means better CPU cache behavior
But still has slight overhead compared to BoxStatefulConsumer:
- Reference Counting: Non-atomic but still exists
- Runtime Borrowing Checks:
RefCellchecks at runtime
§Safety
RcStatefulConsumer is not thread-safe and does not implement Send or Sync.
Attempting to send it to another thread will result in a compilation error.
For thread-safe sharing, use ArcStatefulConsumer instead.
§Examples
use prism3_function::{Consumer, RcStatefulConsumer};
use std::rc::Rc;
use std::cell::RefCell;
let log = Rc::new(RefCell::new(Vec::new()));
let l = log.clone();
let mut consumer = RcStatefulConsumer::new(move |x: &i32| {
l.borrow_mut().push(*x * 2);
});
let mut clone = consumer.clone();
consumer.accept(&5);
assert_eq!(*log.borrow(), vec![10]);§Author
Haixing Hu
Implementations§
Source§impl<T> RcStatefulConsumer<T>where
T: 'static,
impl<T> RcStatefulConsumer<T>where
T: 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new consumer.
Wraps the provided closure in the appropriate smart pointer type for this consumer implementation.
Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a new named consumer.
Wraps the provided closure and assigns it a name, which is useful for debugging and logging purposes.
Sourcepub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
pub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
Creates a new named consumer with an optional name.
Wraps the provided closure and assigns it an optional name.
Sourcepub fn noop() -> Self
pub fn noop() -> Self
Creates a no-operation consumer.
Creates a consumer that does nothing when called. Useful for default values or placeholder implementations.
§Returns
Returns a new consumer instance that performs no operation.
Sourcepub fn when<P>(&self, predicate: P) -> RcConditionalStatefulConsumer<T>where
P: Predicate<T> + 'static,
pub fn when<P>(&self, predicate: P) -> RcConditionalStatefulConsumer<T>where
P: Predicate<T> + 'static,
Creates a conditional consumer
Wraps this consumer with a predicate condition, creating a new conditional consumer that will only execute the original consumer when the predicate evaluates to true.
§Parameters
predicate- The condition that must be satisfied for the consumer to execute
§Returns
Returns a conditional consumer that executes this consumer only when the predicate is satisfied
§Examples
let consumer = ArcConsumer::new(|x: &i32| println!("{}", x));
let conditional = consumer.when(|x| *x > 0);
conditional.accept(&5); // prints: 5
conditional.accept(&-5); // prints nothingSourcepub fn and_then<C>(&self, after: C) -> RcStatefulConsumer<T>where
T: 'static,
C: StatefulConsumer<T> + 'static,
pub fn and_then<C>(&self, after: C) -> RcStatefulConsumer<T>where
T: 'static,
C: StatefulConsumer<T> + 'static,
Chains another consumer in sequence
Combines this consumer with another consumer into a new consumer
that executes both consumers in sequence. The returned consumer
first executes this consumer, then unconditionally executes the
after consumer.
§Parameters
after- The consumer to execute after this one (always executed)
§Returns
Returns a new consumer that executes both consumers in sequence
§Examples
let consumer1 = ArcConsumer::new(|x: &i32| print!("first: {}", x));
let consumer2 = ArcConsumer::new(|x: &i32| println!(" second: {}", x));
let chained = consumer1.and_then(consumer2);
chained.accept(&5); // prints: first: 5 second: 5