cog_task/action/core/
logger.rs1use crate::action::{Action, ActionSignal, Props, StatefulAction, INFINITE};
2use crate::comm::{QWriter, Signal, SignalId};
3use crate::resource::{IoManager, LoggerSignal, ResourceManager};
4use crate::server::{AsyncSignal, Config, State, SyncSignal};
5use eyre::{eyre, Result};
6use serde::{Deserialize, Serialize};
7use std::collections::{BTreeMap, BTreeSet};
8
9#[derive(Debug, Deserialize, Serialize)]
10pub struct Logger {
11 group: String,
12 in_mapping: BTreeMap<SignalId, String>,
13}
14
15stateful!(Logger {
16 group: String,
17 in_mapping: BTreeMap<SignalId, String>,
18});
19
20impl Action for Logger {
21 #[inline]
22 fn in_signals(&self) -> BTreeSet<SignalId> {
23 self.in_mapping.keys().cloned().collect()
24 }
25
26 fn init(self) -> Result<Box<dyn Action>>
27 where
28 Self: 'static + Sized,
29 {
30 if self.group.is_empty() {
31 Err(eyre!("Logger's `group` cannot be empty."))
32 } else if self.in_mapping.is_empty() {
33 Err(eyre!("Logger without `in_mapping` is useless."))
34 } else {
35 Ok(Box::new(self))
36 }
37 }
38
39 fn stateful(
40 &self,
41 _io: &IoManager,
42 _res: &ResourceManager,
43 _config: &Config,
44 _sync_writer: &QWriter<SyncSignal>,
45 _async_writer: &QWriter<AsyncSignal>,
46 ) -> Result<Box<dyn StatefulAction>> {
47 Ok(Box::new(StatefulLogger {
48 done: false,
49 group: self.group.clone(),
50 in_mapping: self.in_mapping.clone(),
51 }))
52 }
53}
54
55impl StatefulAction for StatefulLogger {
56 impl_stateful!();
57
58 fn props(&self) -> Props {
59 INFINITE.into()
60 }
61
62 fn update(
63 &mut self,
64 signal: &ActionSignal,
65 _sync_writer: &mut QWriter<SyncSignal>,
66 async_writer: &mut QWriter<AsyncSignal>,
67 state: &State,
68 ) -> Result<Signal> {
69 let mut entries = vec![];
70 if let ActionSignal::StateChanged(_, signal) = signal {
71 for id in signal {
72 if let Some(name) = self.in_mapping.get(id) {
73 if let Some(value) = state.get(id) {
74 entries.push((name.clone(), value.clone()));
75 }
76 }
77 }
78 }
79
80 async_writer.push(LoggerSignal::Extend(self.group.clone(), entries));
81 Ok(Signal::none())
82 }
83}