rsiot/components_config/http_server/
put_endpoints_collection.rs

1use std::collections::HashMap;
2
3use crate::{
4    message::{Message, MsgDataBound},
5    serde_utils,
6};
7
8use super::PutEndpoint;
9
10/// Коллекция точек PUT
11pub struct PutEndpointsCollection<TMsg>(HashMap<String, Box<dyn PutEndpoint<TMsg>>>);
12
13impl<TMsg> PutEndpointsCollection<TMsg> {
14    /// Создать коллекцию точек PUT на основе конфигурации
15    pub fn new(config_endpoints: &[Box<dyn PutEndpoint<TMsg>>]) -> Self
16    where
17        TMsg: MsgDataBound,
18    {
19        let mut endpoints = HashMap::new();
20        for endpoint in config_endpoints {
21            let key = endpoint.get_path().to_string();
22            let value = endpoint.clone();
23            endpoints.insert(key, value);
24        }
25        Self(endpoints)
26    }
27
28    /// Обработка PUT запроса
29    pub fn handler<TError>(
30        &self,
31        path: &str,
32        body: &[u8],
33        error_unknown_path: fn(String) -> TError,
34        error_serde: fn(serde_utils::Error) -> TError,
35    ) -> Result<Option<Message<TMsg>>, TError> {
36        self.0
37            .get(path)
38            .ok_or_else(|| error_unknown_path(path.to_string()))?
39            .fn_output(body)
40            .map_err(error_serde)
41    }
42
43    /// Информация о точках PUT для `/info`
44    pub fn info(&self) -> String {
45        self.0
46            .keys()
47            .map(|k| format!("<li>{k}</li>"))
48            .collect::<Vec<String>>()
49            .join("\n")
50    }
51
52    /// Массив всех путей PUT
53    pub fn all_paths(&self) -> Vec<String> {
54        self.0.keys().cloned().collect()
55    }
56}