rsiot/components_config/http_server/
get_endpoints_collection.rs

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