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
98
99
100
101
102
103
104
105
106
extern crate alloc;
use slog::{info, o, error};
use crate::{FsmBackend, FsmBackendImpl, FsmEvent, Inspect, InspectEvent, InspectFsmEvent};
use crate::lib::*;
use AsRef;
use core::fmt::Debug;
use core::any::Any;
use alloc::string::ToString;
use alloc::format;
pub struct InspectSlog {
pub logger: slog::Logger
}
impl InspectSlog {
pub fn new(logger: Option<slog::Logger>) -> Self {
InspectSlog {
logger: logger.unwrap_or(slog::Logger::root(slog::Discard, o!()))
}
}
}
impl Inspect for InspectSlog
{
fn new_event<F: FsmBackend>(&self, event: &FsmEvent<<F as FsmBackend>::Events, <F as FsmBackend>::Timers>, fsm: &FsmBackendImpl<F>) -> Self {
let event_display = match event {
FsmEvent::Timer(t) => format!("Fsm::Timer({:?})", t),
_ => event.as_ref().to_string()
};
let current_state = format!("{:?}", fsm.get_current_states());
let kv = o!("event" => event_display, "start_state" => current_state);
info!(self.logger, "Dispatching"; &kv);
InspectSlog {
logger: self.logger.new(kv)
}
}
fn for_transition<T>(&self) -> Self {
let transition = type_name::<T>();
let kv = o!("transition" => transition);
info!(self.logger, "Matched transition"; &kv);
InspectSlog {
logger: self.logger.new(kv)
}
}
fn for_sub_machine<FSub: FsmBackend>(&self) -> Self {
let sub_fsm = type_name::<FSub>();
let kv = o!("sub_fsm" => sub_fsm);
info!(self.logger, "Dispatching to a submachine"; &kv);
InspectSlog {
logger: self.logger.new(kv)
}
}
fn for_timer<F>(&self, timer_id: <F as FsmBackend>::Timers) -> Self where F: FsmBackend {
let kv = o!("timer_id" => format!("{:?}", timer_id));
InspectSlog {
logger: self.logger.new(kv)
}
}
fn on_guard<T>(&self, guard_result: bool) {
let guard = type_name::<T>();
info!(self.logger, "Guard {guard} evaluated to {guard_result}", guard = guard, guard_result = guard_result);
}
fn on_state_enter<S>(&self) {
let state = type_name::<S>();
info!(self.logger, "Entering {state}", state = state);
}
fn on_state_exit<S>(&self) {
let state = type_name::<S>();
info!(self.logger, "Exiting {state}", state = state);
}
fn on_action<S>(&self) {
let action = type_name::<S>();
info!(self.logger, "Executing {action}", action = action);
}
fn event_done<F: FsmBackend>(self, fsm: &FsmBackendImpl<F>) {
let states = format!("{:?}", fsm.get_current_states());
info!(self.logger, "Dispatch done"; "stop_state" => states);
}
fn on_error<E>(&self, msg: &str, error: &E) where E: Debug {
let kv = o!("error" => format!("{:?}", error));
error!(self.logger, "{}", msg; kv);
}
fn info(&self, msg: &str) {
info!(self.logger, "{}", msg);
}
}
impl InspectEvent for InspectSlog
{
fn on_event<S: Any + Debug + Clone>(&self, event: &InspectFsmEvent<S>) {
info!(self.logger, "Inspection event {:?}", event);
}
}