reducer/reactor/
array.rs

1use crate::reactor::*;
2
3/// Notifies all [`Reactor`]s in the array in order.
4///
5/// <small>Currently implemented for arrays of up to 32 elements.</small>
6///
7/// # Example
8///
9/// ```rust
10/// use reducer::*;
11///
12/// struct State { /* ... */ }
13/// struct Action { /* ... */ }
14///
15/// impl Reducer<Action> for State {
16///     fn reduce(&mut self, action: Action) {
17///         // ...
18///     }
19/// }
20///
21/// struct Actor { /* ... */ }
22/// struct ActorError(/*...*/);
23///
24/// impl Reactor<State> for Actor {
25///     type Error = ActorError;
26///     fn react(&mut self, state: &State) -> Result<(), Self::Error> {
27///         // ...
28///         Ok(())
29///     }
30/// }
31///
32/// let a = Actor { /* ... */ };
33/// let b = Actor { /* ... */ };
34/// // ...
35/// let z = Actor { /* ... */ };
36///
37/// let mut store = Store::new(State { /* ... */ }, [a, b, /* ..., */ z]);
38///
39/// // All actors get notified of state changes.
40/// store.dispatch(Action { /* ... */ });
41/// ```
42impl<S, T, const N: usize> Reactor<S> for [T; N]
43where
44    S: ?Sized,
45    T: Reactor<S>,
46{
47    type Error = T::Error;
48
49    fn react(&mut self, state: &S) -> Result<(), Self::Error> {
50        self[..].react(state)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use mockall::predicate::*;
58    use test_strategy::proptest;
59
60    #[proptest]
61    fn react(state: u8, results: [Result<(), u8>; 32]) {
62        let (idx, result) = results
63            .iter()
64            .enumerate()
65            .find(|(_, r)| r.is_err())
66            .map_or((results.len(), Ok(())), |(i, &r)| (i, r));
67
68        let mut reactor: [MockReactor<_, _>; 32] = Default::default();
69
70        for (i, (mock, result)) in reactor.iter_mut().zip(results).enumerate() {
71            mock.expect_react()
72                .with(eq(state))
73                .times(if i > idx { 0 } else { 1 })
74                .return_const(result);
75        }
76
77        assert_eq!(Reactor::react(&mut reactor, &state), result);
78    }
79}