rsiot_messages_core/
message.rs

1use std::fmt::Debug;
2
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6use crate::{MsgData, MsgDataBound, MsgTrace, Timestamp};
7
8#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
9pub struct Message<TCustom> {
10    pub data: MsgData<TCustom>,
11    pub key: String,
12    pub ts: Timestamp,
13    pub trace: MsgTrace,
14}
15
16impl<TCustom> Message<TCustom>
17where
18    TCustom: MsgDataBound,
19{
20    pub fn new(data: MsgData<TCustom>) -> Self {
21        let key = define_key(&data);
22        Self {
23            data,
24            key,
25            ts: Default::default(),
26            trace: MsgTrace::default(),
27        }
28    }
29
30    pub fn new_custom(custom_data: TCustom) -> Self {
31        let data = MsgData::Custom(custom_data);
32        let key = define_key(&data);
33        Self {
34            data,
35            key,
36            ts: Default::default(),
37            trace: MsgTrace::default(),
38        }
39    }
40
41    pub fn get_data(&self) -> Option<TCustom> {
42        match &self.data {
43            MsgData::System(_) => None,
44            MsgData::Custom(data) => Some(data.clone()),
45        }
46    }
47
48    pub fn add_trace_item(&mut self, id: &Uuid, name: &str) {
49        self.trace.insert(*id, name.to_string())
50    }
51
52    /// Проверяем, что в трейсе сообщения присутсвует компонент с заданным id.
53    ///
54    /// Полезно для предотварщения зацикливания сообщений, чтобы данный компонент не обрабатывал
55    /// сообщения, которые он же и сгенерировал
56    pub fn contains_trace_item(&self, id: &Uuid) -> bool {
57        self.trace.contains_key(id)
58    }
59}
60
61/// Определить ключ сообщения по выводу Debug
62fn define_key<TCustom>(data: &MsgData<TCustom>) -> String
63where
64    TCustom: MsgDataBound,
65{
66    let full_str = format!("{:?}", data);
67    let key = full_str.split('(').collect::<Vec<&str>>();
68    // Убираем последний элемент. Если тип unit (), нужно убрать два последних элемента
69    let skip = if key[key.len() - 2].is_empty() { 2 } else { 1 };
70    key[0..key.len() - skip].join("-")
71}