1use crate::plugin::Plugin;
8use std::borrow::Cow;
9use std::fmt;
10use std::sync::{Arc, Mutex};
11
12use ek_event::Event;
13
14pub const EVENT_LOG: &str = "eLog";
15pub const EVENT_PLUG_DOWN_PREFIX: &str = "ePlugQDown.";
16
17pub const EVENT_PLUG_UP: &str = "ePlugUp";
19pub const EVENT_PLUG_DOWN: &str = "ePlugDown";
20pub const EVENT_SRV_CHG: &str = "eSrvChg";
21pub const EVENT_PLUG_UP_PREFIX: &str = "ePlugUp.";
22pub const EVENT_PLUG_DOWN_EVENT_PREFIX: &str = "ePlugDown.";
23pub const EVENT_SRV_CHG_PREFIX: &str = "eSrvChg.";
24
25pub const LOG_LEVEL_INFO: u8 = 20;
27pub const LOG_LEVEL_WARN: u8 = 30;
28pub const LOG_LEVEL_ERROR: u8 = 40;
29
30#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct LogData {
33 pub level: u8,
34 pub source: String,
35 pub msg: String,
36}
37
38impl fmt::Display for LogData {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "[{}] {}: {}", self.level, self.source, self.msg)
41 }
42}
43
44pub type LogSink = Arc<dyn Fn(&LogData) + Send + Sync>;
46
47fn default_console_sink() -> LogSink {
48 Arc::new(|d: &LogData| println!("{d}"))
49}
50
51pub struct LogPlugin {
53 sink: Mutex<LogSink>,
54}
55
56impl LogPlugin {
57 pub fn console() -> Self {
58 Self { sink: Mutex::new(default_console_sink()) }
59 }
60 pub fn with_sink(sink: impl Fn(&LogData) + Send + Sync + 'static) -> Self {
61 Self { sink: Mutex::new(Arc::new(sink)) }
62 }
63 pub fn set_sink(&self, sink: LogSink) {
64 *self.sink.lock().unwrap() = sink;
65 }
66}
67
68impl Plugin for LogPlugin {
69 fn name(&self) -> &str {
70 "log"
71 }
72
73 fn routes(&self) -> Vec<Cow<'static, str>> {
74 vec![Cow::Borrowed(EVENT_LOG)]
75 }
76
77 fn on_mail(&self, event: &Event) {
78 if let Some(d) = event.data.downcast_ref::<LogData>() {
79 let sink = self.sink.lock().unwrap().clone();
80 sink(d);
81 }
82 }
83}