Skip to main content

pilatus_axum/
web_component.rs

1use std::borrow::Cow;
2
3use serde::{ser::SerializeMap, Serialize};
4
5#[derive(serde::Serialize)]
6pub struct DeviceTopicWebComponentLocation {
7    pub device_type: &'static str,
8    pub topic: &'static str,
9    pub target: &'static str,
10}
11
12/// Specify locations for webcomponents of any kind
13/// Just the first part before the slash is considered for mapping
14/// - for 'my-device/test', only 'my-device' should be mapped
15/// - for 'other', the entire word 'other' should be mapped
16pub struct WebComponentLocation(WebComponentLocationKind);
17
18impl WebComponentLocation {
19    pub fn new(
20        component_id: impl Into<Cow<'static, str>>,
21        target: impl Into<Cow<'static, str>>,
22    ) -> Self {
23        WebComponentLocation(WebComponentLocationKind::Raw(
24            component_id.into(),
25            target.into(),
26        ))
27    }
28}
29
30enum WebComponentLocationKind {
31    DeviceTopic(DeviceTopicWebComponentLocation),
32    Raw(Cow<'static, str>, Cow<'static, str>),
33}
34
35pub struct WebComponentLocations(Vec<WebComponentLocation>);
36impl Serialize for WebComponentLocations {
37    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38    where
39        S: serde::Serializer,
40    {
41        let mut map = serializer.serialize_map(None)?;
42        for item in self.0.iter() {
43            match &item.0 {
44                WebComponentLocationKind::DeviceTopic(d) => {
45                    map.serialize_entry(&format_args!("{}/{}", d.device_type, d.topic), d.target)?
46                }
47                WebComponentLocationKind::Raw(component_id, target) => {
48                    map.serialize_entry(component_id, target)?
49                }
50            };
51        }
52        map.end()
53    }
54}
55
56impl FromIterator<WebComponentLocation> for WebComponentLocations {
57    fn from_iter<T: IntoIterator<Item = WebComponentLocation>>(iter: T) -> Self {
58        Self(iter.into_iter().collect())
59    }
60}
61
62impl From<DeviceTopicWebComponentLocation> for WebComponentLocation {
63    fn from(value: DeviceTopicWebComponentLocation) -> Self {
64        WebComponentLocation(WebComponentLocationKind::DeviceTopic(value))
65    }
66}