reactive_state/middleware/
mod.rs

1//! [Middleware] used to modify the behaviour of a [Store] during a
2//! [Store::dispatch()]. This module also contains some simple
3//! middleware implementations which can be used as utilities in an
4//! application.
5
6#[cfg(feature = "simple_logger")]
7#[cfg_attr(docsrs, doc(cfg(feature = "simple_logger")))]
8pub mod simple_logger;
9
10#[cfg(feature = "web_logger")]
11#[cfg_attr(docsrs, doc(cfg(feature = "web_logger")))]
12pub mod web_logger;
13
14use crate::Store;
15
16pub struct ReduceMiddlewareResult<Event, Effect> {
17    pub events: Vec<Event>,
18    pub effects: Vec<Effect>,
19}
20
21impl<Event, Effect> Default for ReduceMiddlewareResult<Event, Effect> {
22    fn default() -> Self {
23        ReduceMiddlewareResult {
24            events: Vec::new(),
25            effects: Vec::new(),
26        }
27    }
28}
29
30/// Executes subsequent middleware and then runs the [Reducer](crate::Reducer).
31pub type ReduceFn<State, Action, Event, Effect> = fn(
32    &Store<State, Action, Event, Effect>,
33    Option<&Action>,
34) -> ReduceMiddlewareResult<Event, Effect>;
35
36/// Executes subsequent middleware and then notifies the listeners.
37pub type NotifyFn<State, Action, Event, Effect> =
38    fn(&Store<State, Action, Event, Effect>, Vec<Event>) -> Vec<Event>;
39
40/// `Middleware` used to modify the behaviour of a [Store] during a
41/// [Store::dispatch()].
42pub trait Middleware<State, Action, Event, Effect> {
43    /// This method is invoked by the [Store] during a
44    /// [Store::dispatch()] just before the `Action` is sent to the
45    /// [Reducer](crate::Reducer). It is necessary to call the
46    /// provided `reduce` function, which executes subsequent
47    /// middleware and runs the [Reducer](crate::Reducer), and usually
48    /// the events produced by the `reduce` function are returned from
49    /// this method.
50    ///
51    /// This method allows modifying the action in question, or even
52    /// removing it, preventing the [Reducer](crate::Reducer) from
53    /// processing the action. It also allows modifying the events
54    /// produced by the [Reducer](crate::Reducer) before the
55    /// [Middleware::on_notify()] is invoked and they are sent to the
56    /// [Store] listeners.
57    fn on_reduce(
58        &self,
59        store: &Store<State, Action, Event, Effect>,
60        action: Option<&Action>,
61        reduce: ReduceFn<State, Action, Event, Effect>,
62    ) -> ReduceMiddlewareResult<Event, Effect> {
63        reduce(store, action)
64    }
65
66    /// Process an `Effect`. Returns `None` if the effect was
67    /// processed/consumed by this handler, otherwise returns
68    /// `Some(effect)`.
69    fn process_effect(
70        &self,
71        _store: &Store<State, Action, Event, Effect>,
72        effect: Effect,
73    ) -> Option<Effect> {
74        Some(effect)
75    }
76
77    /// This method is invoked by the [Store] during a
78    /// [Store::dispatch()] after the [Reducer](crate::Reducer) has
79    /// processed the `Action` and all [Middleware::on_reduce()]
80    /// methods have completed, just before resulting events are
81    /// sent to the store listeners. It is necessary to call the
82    /// provided `notify` function, which executes subsequent
83    /// middleware and then notifies the listeners.
84    ///
85    /// This method allows modifying the events in question before the
86    /// listeners are notified.
87    fn on_notify(
88        &self,
89        store: &Store<State, Action, Event, Effect>,
90        events: Vec<Event>,
91        notify: NotifyFn<State, Action, Event, Effect>,
92    ) -> Vec<Event> {
93        notify(store, events)
94    }
95}