1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
mod array;
mod mock;
mod option;
mod reference;
mod sender;
mod slice;
mod tuple;
/// Trait for types that react to state transitions.
///
/// Reactors connect the _state_ to the _view_ components. They can implement arbitrary logic in
/// response to state transitions, but it's often better to think of Reactors as _channels_ that
/// transmit the current state to other parts of your application.
///
/// # Reactor as a Data Channel
/// For GUI applications, it is a good practice to have a separate thread dedicated to rendering.
/// To help wiring up the Flux pattern in such multi-threaded scenarios, Reactor is implemented
/// for [`mpsc::Sender`](trait.Reactor.html#impl-Reactor<S>) out of the box.
///
/// ## Example
/// ```rust
/// use reducer::*;
///
/// fn main() {
/// // Create a channel for the current state.
/// let (tx, rx) = std::sync::mpsc::channel();
///
/// // Start the rendering thread.
/// std::thread::spawn(move || {
/// while let Ok(Countdown(t)) = rx.recv() {
/// // Render the current state to the screen.
/// match t {
/// 6 => println!("T-6 seconds - Main engine start."),
/// 0 => println!("T-0 seconds - Solid rocket booster ignition and liftoff!"),
/// t if t > 0 => println!("T-{} seconds", t),
/// _ => break,
/// }
/// }
/// });
///
/// #[derive(Clone)]
/// struct Countdown(i32);
///
/// struct Tick;
/// impl Reducer<Tick> for Countdown {
/// fn reduce(&mut self, _: Tick) {
/// self.0 -= 1;
/// }
/// }
///
/// // Set-up the initial state.
/// let mut store = Store::new(Countdown(10), tx);
///
/// // Count down to liftoff!
/// while let Ok(()) = store.dispatch(Tick) {}
/// }
/// ```
pub trait Reactor<S> {
/// The result of reacting to `S`.
type Output;
/// Reacts to `S` and produces `Self::Output`.
///
/// # Example
/// ```rust
/// use reducer::*;
/// use std::fmt::Debug;
/// use std::io::{self, Write};
///
/// struct Console;
///
/// impl<T: Debug> Reactor<T> for Console {
/// type Output = io::Result<()>;
/// fn react(&self, state: &T) -> Self::Output {
/// io::stdout().write_fmt(format_args!("{:?}\n", state))
/// }
/// }
/// ```
fn react(&self, state: &S) -> Self::Output;
}
#[cfg(test)]
pub use self::mock::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn react() {
let reactor: &Reactor<_, Output = _> = &MockReactor;
assert_eq!(reactor.react(&5), 5);
assert_eq!(reactor.react(&1), 1);
assert_eq!(reactor.react(&3), 3);
}
}