astarte_device_sdk/session/
mod.rs1use std::future::Future;
23
24use astarte_interfaces::Interface;
25use itertools::Itertools;
26
27use crate::{error::DynError, interfaces::Interfaces};
28
29mod sqlite;
30
31#[derive(Debug, Clone, Copy, Eq, PartialOrd, Ord, Hash)]
33pub struct IntrospectionInterface<S = String> {
34 name: S,
36 version_major: i32,
38 version_minor: i32,
40}
41
42impl<S> IntrospectionInterface<S> {
43 pub fn new(name: S, version_major: i32, version_minor: i32) -> Self {
45 Self {
46 name,
47 version_major,
48 version_minor,
49 }
50 }
51
52 pub fn name(&self) -> &S {
54 &self.name
55 }
56 pub fn version_major(&self) -> i32 {
58 self.version_major
59 }
60 pub fn version_minor(&self) -> i32 {
62 self.version_minor
63 }
64}
65
66impl<T: PartialEq<U>, U> PartialEq<IntrospectionInterface<U>> for IntrospectionInterface<T> {
67 fn eq(&self, other: &IntrospectionInterface<U>) -> bool {
68 self.name() == other.name()
69 && self.version_major() == other.version_major()
70 && self.version_minor() == other.version_minor()
71 }
72}
73
74impl<'a> From<&'a Interface> for IntrospectionInterface<&'a str> {
75 fn from(val: &'a Interface) -> Self {
76 IntrospectionInterface::new(
77 val.interface_name(),
78 val.version_major(),
79 val.version_minor(),
80 )
81 }
82}
83
84impl From<&Interface> for IntrospectionInterface {
85 fn from(val: &Interface) -> Self {
86 IntrospectionInterface::new(
87 val.interface_name().to_owned(),
88 val.version_major(),
89 val.version_minor(),
90 )
91 }
92}
93
94impl<'a> From<&'a Interfaces> for Vec<IntrospectionInterface<&'a str>> {
95 fn from(val: &'a Interfaces) -> Self {
96 val.iter().map(|i| i.into()).collect_vec()
97 }
98}
99
100impl From<&Interfaces> for Vec<IntrospectionInterface> {
101 fn from(val: &Interfaces) -> Self {
102 val.iter().map(|i| i.into()).collect_vec()
103 }
104}
105
106impl From<IntrospectionInterface<&str>> for IntrospectionInterface {
107 fn from(value: IntrospectionInterface<&str>) -> Self {
108 IntrospectionInterface {
109 name: value.name.to_string(),
110 version_major: value.version_major,
111 version_minor: value.version_minor,
112 }
113 }
114}
115
116#[derive(Debug, thiserror::Error)]
118#[non_exhaustive]
119pub enum SessionError {
120 #[error("couldn't store the introspection")]
122 AddInterfaces(#[source] DynError),
123 #[error("couldn't load the introspection")]
125 LoadIntrospection(#[source] DynError),
126 #[error("couldn't remove the interfaces")]
128 RemoveInterfaces(#[source] DynError),
129}
130
131impl SessionError {
132 pub(crate) fn add_interfaces(err: impl Into<DynError>) -> Self {
133 Self::AddInterfaces(err.into())
134 }
135
136 pub(crate) fn load_introspection(err: impl Into<DynError>) -> Self {
137 Self::LoadIntrospection(err.into())
138 }
139
140 pub(crate) fn remove_interfaces(err: impl Into<DynError>) -> Self {
141 Self::RemoveInterfaces(err.into())
142 }
143}
144
145pub trait StoredSession: Clone + Send + Sync {
147 fn clear_introspection(&self) -> impl Future<Output = ()> + Send;
151
152 fn store_introspection(
158 &self,
159 interfaces: &[IntrospectionInterface],
160 ) -> impl Future<Output = ()> + Send;
161
162 fn add_interfaces(
164 &self,
165 interfaces: &[IntrospectionInterface<&str>],
166 ) -> impl Future<Output = Result<(), SessionError>> + Send;
167
168 fn load_introspection(
170 &self,
171 ) -> impl Future<Output = Result<Vec<IntrospectionInterface>, SessionError>> + Send;
172
173 fn remove_interfaces(
175 &self,
176 interfaces: &[IntrospectionInterface<&str>],
177 ) -> impl Future<Output = Result<(), SessionError>> + Send;
178}
179
180#[cfg(test)]
181pub(crate) mod tests {
182 use std::str::FromStr;
183
184 use astarte_interfaces::Interface;
185 use pretty_assertions::assert_eq;
186
187 use crate::test::{DEVICE_OBJECT, DEVICE_PROPERTIES, SERVER_INDIVIDUAL};
188
189 use super::IntrospectionInterface;
190
191 impl<'a> From<&'a IntrospectionInterface> for IntrospectionInterface<&'a str> {
192 fn from(val: &'a IntrospectionInterface) -> Self {
193 IntrospectionInterface::new(val.name(), val.version_major(), val.version_minor())
194 }
195 }
196
197 impl IntrospectionInterface {
198 pub(crate) fn as_ref(&self) -> IntrospectionInterface<&str> {
199 self.into()
200 }
201 }
202
203 #[test]
204 fn test_from_interface() {
205 let interface = Interface::from_str(DEVICE_OBJECT).unwrap();
206
207 let introspection_if_data_ref: IntrospectionInterface<&str> = From::from(&interface);
208
209 assert_eq!(interface.interface_name(), introspection_if_data_ref.name);
210 assert_eq!(
211 interface.version_major(),
212 introspection_if_data_ref.version_major
213 );
214 assert_eq!(
215 interface.version_minor(),
216 introspection_if_data_ref.version_minor
217 );
218
219 let introspection_if_data: IntrospectionInterface = From::from(&interface);
220
221 assert_eq!(interface.interface_name(), introspection_if_data.name);
222 assert_eq!(
223 interface.version_major(),
224 introspection_if_data.version_major
225 );
226 assert_eq!(
227 interface.version_minor(),
228 introspection_if_data.version_minor
229 );
230
231 assert_eq!(introspection_if_data_ref, introspection_if_data.as_ref());
232 }
233
234 #[test]
235 fn test_from_interfaces() {
236 use crate::session::Interfaces;
237
238 let interfaces = [
239 Interface::from_str(DEVICE_PROPERTIES).unwrap(),
240 Interface::from_str(DEVICE_OBJECT).unwrap(),
241 Interface::from_str(SERVER_INDIVIDUAL).unwrap(),
242 ];
243
244 let interfaces = Interfaces::from_iter(interfaces);
245
246 let introsopection_interface_vec: Vec<IntrospectionInterface<&str>> =
247 From::from(&interfaces);
248
249 assert!(interfaces.matches(&introsopection_interface_vec));
250
251 let introsopection_interface_vec: Vec<IntrospectionInterface> = From::from(&interfaces);
252
253 assert!(interfaces.matches(&introsopection_interface_vec));
254 }
255}