rsiot/components_config/http_client/
request_input.rs

1use std::fmt::Debug;
2
3use tracing::warn;
4
5use crate::{
6    components_config::http_general::HttpDataBound,
7    message::MsgDataBound,
8    serde_utils::{SerdeAlg, SerdeAlgKind},
9};
10
11use super::{
12    FnCreateRequest, FnProcessResponseError, FnProcessResponseSuccess, MsgRequest, MsgResponse,
13    RequestKind,
14};
15
16/// Параметры запроса на основе входящего потока сообщений
17#[derive(Clone, Debug)]
18pub struct RequestInputConfig<TMsg, TServerToClient, TClientToServer> {
19    /// Алгоритм сериализации / десериализации
20    pub serde_alg: SerdeAlgKind,
21    /// Тип HTTP-запроса
22    pub request_kind: RequestKind,
23    /// Путь к ресурсу
24    pub endpoint: String,
25    /// Функция выдает параметры запроса, на основе входных сообщений
26    pub fn_create_request: FnCreateRequest<TMsg, TClientToServer>,
27    /// Функция обработки корректного ответа
28    pub fn_process_response_success: FnProcessResponseSuccess<TMsg, TServerToClient>,
29    /// Функция обработки ошибки ответа
30    pub fn_process_response_error: FnProcessResponseError<TMsg>,
31}
32
33/// Трейт для реализации запросов на основе входящего потока сообщений
34pub trait RequestInput<TMsg>
35where
36    Self: Debug + Send + Sync,
37{
38    /// Создание запроса
39    fn create_request(&self, msg: &TMsg) -> Option<MsgRequest>;
40
41    /// Обработка ответа
42    fn process_response(&self, msg_response: &MsgResponse) -> Option<Vec<TMsg>>;
43
44    /// Поддержка клонирования
45    fn clone_dyn(&self) -> Box<dyn RequestInput<TMsg>>;
46}
47
48impl<TMsg> Clone for Box<dyn RequestInput<TMsg>> {
49    fn clone(&self) -> Self {
50        self.clone_dyn()
51    }
52}
53
54impl<TMsg, TServerToClient, TClientToServer> RequestInput<TMsg>
55    for RequestInputConfig<TMsg, TServerToClient, TClientToServer>
56where
57    TMsg: 'static + MsgDataBound,
58    TClientToServer: 'static + HttpDataBound,
59    TServerToClient: 'static + HttpDataBound,
60{
61    fn create_request(&self, msg: &TMsg) -> Option<MsgRequest> {
62        let body = (self.fn_create_request)(msg)?;
63
64        let serde_alg = SerdeAlg::new(self.serde_alg);
65        let body_bytes = serde_alg.serialize(&body);
66        let body_bytes = match body_bytes {
67            Ok(v) => v,
68            Err(e) => {
69                warn!("Error serializing http request: {}", e);
70                return None;
71            }
72        };
73
74        let msg_request = MsgRequest::new(self.request_kind, self.endpoint.clone(), body_bytes);
75        Some(msg_request)
76    }
77
78    fn process_response(&self, msg_response: &MsgResponse) -> Option<Vec<TMsg>> {
79        if msg_response.get_endpoint() != &self.endpoint {
80            return None;
81        }
82
83        super::process_response::process_response(
84            self.serde_alg,
85            self.fn_process_response_success,
86            self.fn_process_response_error,
87            msg_response,
88        )
89    }
90
91    fn clone_dyn(&self) -> Box<dyn RequestInput<TMsg>> {
92        Box::new(self.clone())
93    }
94}