rsiot/components_config/http_server/
get_endpoint.rs

1//! Структура хранения данных точки GET
2
3use std::fmt::Debug;
4
5use serde::{de::DeserializeOwned, Serialize};
6
7use crate::{
8    message::MsgDataBound,
9    serde_utils::{self, SerdeAlg, SerdeAlgKind},
10};
11
12/// Конфигурация отдельной точки GET
13#[derive(Clone, Debug)]
14pub struct GetEndpointConfig<TMsg, TServerToClient> {
15    /// Алгоритм сериализации / десериализации
16    pub serde_alg: SerdeAlgKind,
17
18    /// Путь
19    ///
20    /// Примеры:
21    ///
22    /// ```rust
23    /// path: `/data`
24    /// ```
25    pub path: &'static str,
26
27    /// Данные для точки GET
28    ///
29    /// На входной структуре необходимо реализовать:
30    ///
31    /// ```rust
32    /// #[derive(Clone, Debug, Default, Deserialize, Serialize)]
33    /// ```
34    pub server_to_client_data: TServerToClient,
35
36    /// Функция обновления данных на основе входящих сообщений
37    pub fn_input: fn(&TMsg, &mut TServerToClient),
38}
39
40impl<TMsg, TServerToClient> GetEndpoint<TMsg> for GetEndpointConfig<TMsg, TServerToClient>
41where
42    TMsg: 'static + MsgDataBound,
43    TServerToClient: 'static + Clone + Debug + DeserializeOwned + Serialize + Send + Sync,
44{
45    fn get_path(&self) -> &str {
46        self.path
47    }
48
49    fn fn_input(&mut self, msg: &TMsg) {
50        (self.fn_input)(msg, &mut self.server_to_client_data)
51    }
52
53    fn serialize(&self) -> Result<Vec<u8>, serde_utils::Error> {
54        let serde_alg = SerdeAlg::new(self.serde_alg);
55        serde_alg.serialize(&self.server_to_client_data)
56    }
57
58    fn clone_dyn(&self) -> Box<dyn GetEndpoint<TMsg>> {
59        Box::new(self.clone())
60    }
61}
62
63/// Трейт для обеспечения логики работы отдельной точки GET
64///
65/// В разных точках хранят данные в разных структурах (поле `data`). Трейт нужен для обработки в
66/// массиве
67pub trait GetEndpoint<TMsg>
68where
69    Self: Debug + Send + Sync,
70{
71    /// Получить путь для роутера
72    fn get_path(&self) -> &str;
73
74    /// Сериализация данных
75    fn serialize(&self) -> Result<Vec<u8>, serde_utils::Error>;
76
77    /// Обновление данных на основе входящих сообщений
78    fn fn_input(&mut self, msg: &TMsg);
79
80    /// Поддержка клонирования
81    fn clone_dyn(&self) -> Box<dyn GetEndpoint<TMsg>>;
82}
83
84impl<TMsg> Clone for Box<dyn GetEndpoint<TMsg>> {
85    fn clone(&self) -> Self {
86        self.clone_dyn()
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    use std::collections::HashMap;
95
96    use serde::{Deserialize, Serialize};
97
98    use crate::message::example_message::Custom;
99
100    #[test]
101    fn test1() {
102        let mut vec_trait: Vec<Box<dyn GetEndpoint<Custom>>> = vec![];
103
104        #[derive(Clone, Debug, Deserialize, Serialize)]
105        struct Data1 {}
106
107        #[derive(Clone, Debug, Deserialize, Serialize)]
108        struct Data2 {}
109
110        let end1 = GetEndpointConfig {
111            serde_alg: SerdeAlgKind::Json,
112            path: "/1",
113            server_to_client_data: Data1 {},
114            fn_input: |_, _| (),
115        };
116        let end2 = GetEndpointConfig {
117            serde_alg: SerdeAlgKind::Json,
118            path: "/2",
119            server_to_client_data: Data2 {},
120            fn_input: |_, _| (),
121        };
122        vec_trait.push(Box::new(end1));
123        vec_trait.push(Box::new(end2));
124
125        // Собираем в словарь
126        let mut map = HashMap::new();
127
128        for e in vec_trait.into_iter() {
129            let endpoint = e.get_path().to_string();
130            map.insert(endpoint, e);
131        }
132    }
133}