reactive_state/middleware/
simple_logger.rs1use super::ReduceMiddlewareResult;
6use crate::{
7 middleware::{Middleware, ReduceFn},
8 Store,
9};
10use std::{fmt::Debug, hash::Hash};
11
12pub enum LogLevel {
13 Trace,
14 Debug,
15 Warn,
16 Info,
17}
18
19impl LogLevel {
20 pub fn log<S: AsRef<str>>(&self, message: S) {
21 match self {
22 LogLevel::Trace => log::trace!("{}", message.as_ref()),
23 LogLevel::Debug => log::debug!("{}", message.as_ref()),
24 LogLevel::Warn => log::warn!("{}", message.as_ref()),
25 LogLevel::Info => log::info!("{}", message.as_ref()),
26 }
27 }
28}
29
30impl Default for LogLevel {
31 fn default() -> Self {
32 LogLevel::Debug
33 }
34}
35
36pub struct SimpleLoggerMiddleware {
42 log_level: LogLevel,
43}
44
45impl SimpleLoggerMiddleware {
46 pub fn new() -> Self {
47 SimpleLoggerMiddleware {
48 log_level: LogLevel::default(),
49 }
50 }
51
52 pub fn log_level(mut self, log_level: LogLevel) -> Self {
53 self.log_level = log_level;
54 self
55 }
56}
57
58impl Default for SimpleLoggerMiddleware {
59 fn default() -> Self {
60 SimpleLoggerMiddleware::new()
61 }
62}
63
64impl<State, Action, Event, Effect> Middleware<State, Action, Event, Effect>
65 for SimpleLoggerMiddleware
66where
67 Event: Clone + Hash + Eq + Debug,
68 State: Debug,
69 Action: Debug,
70 Effect: Debug,
71{
72 fn on_reduce(
73 &self,
74 store: &Store<State, Action, Event, Effect>,
75 action: Option<&Action>,
76 reduce: ReduceFn<State, Action, Event, Effect>,
77 ) -> ReduceMiddlewareResult<Event, Effect> {
78 let was_action = match &action {
79 Some(action) => {
80 self.log_level
81 .log(format!("prev state: {:?}", store.state()));
82 self.log_level.log(format!("action: {:?}", action));
83 true
84 }
85 None => {
86 self.log_level.log("action: None");
87 false
88 }
89 };
90
91 let events = reduce(store, action);
92
93 if was_action {
94 self.log_level
95 .log(format!("next state: {:?}", store.state()));
96 }
97
98 events
99 }
100
101 fn process_effect(
102 &self,
103 _store: &Store<State, Action, Event, Effect>,
104 effect: Effect,
105 ) -> Option<Effect> {
106 self.log_level.log(format!("effect: {:?}", effect));
107 Some(effect)
108 }
109
110 fn on_notify(
111 &self,
112 store: &Store<State, Action, Event, Effect>,
113 events: Vec<Event>,
114 notify: super::NotifyFn<State, Action, Event, Effect>,
115 ) -> Vec<Event> {
116 for event in &events {
117 self.log_level.log(format!("event: {:?}", event));
118 }
119
120 notify(store, events)
121 }
122}