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}