Skip to main content

rsiot/components_config/http_server/
put_endpoint.rs

1use std::fmt::Debug;
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{
6    message::{Message, MsgDataBound},
7    serde_utils::{self, SerdeAlg, SerdeAlgKind},
8};
9
10// ANCHOR: PutEndpointConfig
11/// Конфигурация отдельной точки PUT
12#[derive(Clone, Debug)]
13pub struct PutEndpointConfig<TMsg, TData>
14where
15    TMsg: MsgDataBound,
16{
17    /// Алгоритм сериализации / десериализации
18    pub serde_alg: SerdeAlgKind,
19
20    /// Путь
21    ///
22    /// Примеры:
23    ///
24    /// ```rust
25    /// path: `/data`
26    /// ```
27    pub path: &'static str,
28
29    /// Функция создания исходящих сообщений на основе входящих данных
30    pub fn_output: fn(data: TData) -> Option<Message<TMsg>>,
31}
32// ANCHOR: PutEndpointConfig
33
34impl<TMsg, TData> PutEndpoint<TMsg> for PutEndpointConfig<TMsg, TData>
35where
36    TData: 'static + Clone + Debug + DeserializeOwned + Serialize + Send + Sync,
37    TMsg: 'static + MsgDataBound,
38{
39    fn get_path(&self) -> &str {
40        self.path
41    }
42
43    fn fn_output(&self, request_body: &[u8]) -> Result<Option<Message<TMsg>>, serde_utils::Error> {
44        let serde_alg = SerdeAlg::new(self.serde_alg);
45        let data: TData = serde_alg.deserialize(request_body)?;
46        let msg = (self.fn_output)(data);
47        Ok(msg)
48    }
49
50    fn clone_dyn(&self) -> Box<dyn PutEndpoint<TMsg>> {
51        Box::new(self.clone())
52    }
53}
54
55/// Трейт для обеспечения логики работы отдельной точик PUT
56///
57/// В разных точках хранят данные в разных структурах (поле `data`). Трейт нужен для обработки в
58/// массиве
59pub trait PutEndpoint<TMsg>
60where
61    Self: Debug + Send + Sync,
62{
63    /// Получить путь для роутера
64    fn get_path(&self) -> &str;
65
66    /// Создание исходящих сообщений на основе входящих данных
67    fn fn_output(&self, request_body: &[u8]) -> Result<Option<Message<TMsg>>, serde_utils::Error>;
68
69    /// Поддержка клонирования
70    fn clone_dyn(&self) -> Box<dyn PutEndpoint<TMsg>>;
71}
72
73impl<TMsg> Clone for Box<dyn PutEndpoint<TMsg>> {
74    fn clone(&self) -> Self {
75        self.clone_dyn()
76    }
77}