edgehog_device_runtime_containers/properties/
mod.rs1use astarte_device_sdk::AstarteData;
22use async_trait::async_trait;
23use tracing::error;
24use uuid::Uuid;
25
26cfg_if::cfg_if! {
27 if #[cfg(test)] {
28 pub use astarte_device_sdk_mock::Client;
29 } else {
30 pub use astarte_device_sdk::Client;
31 }
32}
33
34pub(crate) mod container;
35pub(crate) mod deployment;
36pub(crate) mod device_mapping;
37pub(crate) mod image;
38pub(crate) mod network;
39pub(crate) mod volume;
40
41#[derive(Debug, thiserror::Error, displaydoc::Display)]
43pub enum PropertyError {
44 Send {
46 interface: String,
48 endpoint: String,
50 },
51 Unset {
53 interface: String,
55 endpoint: String,
57 },
58}
59
60#[async_trait]
61pub(crate) trait AvailableProp {
62 type Data: Into<AstarteData> + Send + 'static;
63
64 fn interface() -> &'static str;
65
66 fn field() -> &'static str;
67
68 fn id(&self) -> &Uuid;
69
70 async fn send<D>(&self, device: &mut D, data: Self::Data) -> Result<(), PropertyError>
71 where
72 D: Client + Send + Sync + 'static,
73 {
74 self.send_field(device, Self::field(), data).await
75 }
76
77 async fn send_field<D, T>(
78 &self,
79 device: &mut D,
80 field: &str,
81 data: T,
82 ) -> Result<(), PropertyError>
83 where
84 D: Client + Send + Sync + 'static,
85 T: Into<AstarteData> + Send + 'static,
86 {
87 let interface = Self::interface();
88 let endpoint = format!("/{}/{}", self.id(), field);
89
90 device
91 .set_property(interface, &endpoint, data.into())
92 .await
93 .map_err(|err| {
94 error!(
95 error = format!("{:#}", eyre::Report::new(err)),
96 "couldn't send data for {interface}{endpoint}"
97 );
98
99 PropertyError::Send {
100 interface: interface.to_string(),
101 endpoint,
102 }
103 })
104 }
105
106 async fn unset<D>(&self, device: &mut D) -> Result<(), PropertyError>
107 where
108 D: Client + Send + Sync + 'static,
109 {
110 let interface = Self::interface();
111 let field = Self::field();
112 let endpoint = format!("/{}/{}", self.id(), field);
113
114 device
115 .unset_property(interface, &endpoint)
116 .await
117 .map_err(|err| {
118 error!(
119 error = format!("{:#}", eyre::Report::new(err)),
120 "couldn't unset data for {interface}{endpoint}"
121 );
122
123 PropertyError::Unset {
124 interface: interface.to_string(),
125 endpoint,
126 }
127 })
128 }
129}