mbus_api/
models.rs

1#![allow(unused_qualifications)]
2
3use crate::models;
4#[cfg(any(feature = "client", feature = "server"))]
5use crate::header;
6
7
8/// Slave address (primary or secondary)
9#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
10#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
11pub struct Address(String);
12
13impl std::convert::From<String> for Address {
14    fn from(x: String) -> Self {
15        Address(x)
16    }
17}
18
19impl std::string::ToString for Address {
20    fn to_string(&self) -> String {
21       self.0.to_string()
22    }
23}
24
25impl std::str::FromStr for Address {
26    type Err = std::string::ParseError;
27    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
28        std::result::Result::Ok(Address(x.to_string()))
29    }
30}
31
32impl std::convert::From<Address> for String {
33    fn from(x: Address) -> Self {
34        x.0
35    }
36}
37
38impl std::ops::Deref for Address {
39    type Target = String;
40    fn deref(&self) -> &String {
41        &self.0
42    }
43}
44
45impl std::ops::DerefMut for Address {
46    fn deref_mut(&mut self) -> &mut String {
47        &mut self.0
48    }
49}
50
51
52impl Address {
53    /// Helper function to allow us to convert this model to an XML string.
54    /// Will panic if serialisation fails.
55    #[allow(dead_code)]
56    pub(crate) fn to_xml(&self) -> String {
57        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
58    }
59}
60
61/// Baudrate to use for the communication - valid values 300, 600, 1200, 2400, 4800, 9600
62/// Enumeration of values.
63/// Since this enum's variants do not hold data, we can easily define them them as `#[repr(C)]`
64/// which helps with FFI.
65#[allow(non_camel_case_types)]
66#[repr(C)]
67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
68#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]
69pub enum Baudrate { 
70    #[serde(rename = "300")]
71    _300,
72    #[serde(rename = "600")]
73    _600,
74    #[serde(rename = "1200")]
75    _1200,
76    #[serde(rename = "2400")]
77    _2400,
78    #[serde(rename = "4800")]
79    _4800,
80    #[serde(rename = "9600")]
81    _9600,
82}
83
84impl std::fmt::Display for Baudrate {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        match *self { 
87            Baudrate::_300 => write!(f, "{}", "300"),
88            Baudrate::_600 => write!(f, "{}", "600"),
89            Baudrate::_1200 => write!(f, "{}", "1200"),
90            Baudrate::_2400 => write!(f, "{}", "2400"),
91            Baudrate::_4800 => write!(f, "{}", "4800"),
92            Baudrate::_9600 => write!(f, "{}", "9600"),
93        }
94    }
95}
96
97impl std::str::FromStr for Baudrate {
98    type Err = String;
99
100    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
101        match s {
102            "300" => std::result::Result::Ok(Baudrate::_300),
103            "600" => std::result::Result::Ok(Baudrate::_600),
104            "1200" => std::result::Result::Ok(Baudrate::_1200),
105            "2400" => std::result::Result::Ok(Baudrate::_2400),
106            "4800" => std::result::Result::Ok(Baudrate::_4800),
107            "9600" => std::result::Result::Ok(Baudrate::_9600),
108            _ => std::result::Result::Err(format!("Value not valid: {}", s)),
109        }
110    }
111}
112
113impl Baudrate {
114    /// Helper function to allow us to convert this model to an XML string.
115    /// Will panic if serialisation fails.
116    #[allow(dead_code)]
117    pub(crate) fn to_xml(&self) -> String {
118        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
119    }
120}
121
122/// The device the M-Bus is connected to - /dev/ is prepended to {device} by M-Bus HTTPD
123#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
124#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
125pub struct Device(String);
126
127impl std::convert::From<String> for Device {
128    fn from(x: String) -> Self {
129        Device(x)
130    }
131}
132
133impl std::string::ToString for Device {
134    fn to_string(&self) -> String {
135       self.0.to_string()
136    }
137}
138
139impl std::str::FromStr for Device {
140    type Err = std::string::ParseError;
141    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
142        std::result::Result::Ok(Device(x.to_string()))
143    }
144}
145
146impl std::convert::From<Device> for String {
147    fn from(x: Device) -> Self {
148        x.0
149    }
150}
151
152impl std::ops::Deref for Device {
153    type Target = String;
154    fn deref(&self) -> &String {
155        &self.0
156    }
157}
158
159impl std::ops::DerefMut for Device {
160    fn deref_mut(&mut self) -> &mut String {
161        &mut self.0
162    }
163}
164
165
166impl Device {
167    /// Helper function to allow us to convert this model to an XML string.
168    /// Will panic if serialisation fails.
169    #[allow(dead_code)]
170    pub(crate) fn to_xml(&self) -> String {
171        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
172    }
173}
174
175/// Raspberry Pi Hat Information
176// Methods for converting between header::IntoHeaderValue<Hat> and hyper::header::HeaderValue
177
178#[cfg(any(feature = "client", feature = "server"))]
179impl std::convert::TryFrom<header::IntoHeaderValue<Hat>> for hyper::header::HeaderValue {
180    type Error = String;
181
182    fn try_from(hdr_value: header::IntoHeaderValue<Hat>) -> std::result::Result<Self, Self::Error> {
183        let hdr_value = hdr_value.to_string();
184        match hyper::header::HeaderValue::from_str(&hdr_value) {
185             std::result::Result::Ok(value) => std::result::Result::Ok(value),
186             std::result::Result::Err(e) => std::result::Result::Err(
187                 format!("Invalid header value for Hat - value: {} is invalid {}",
188                     hdr_value, e))
189        }
190    }
191}
192
193#[cfg(any(feature = "client", feature = "server"))]
194impl std::convert::TryFrom<hyper::header::HeaderValue> for header::IntoHeaderValue<Hat> {
195    type Error = String;
196
197    fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result<Self, Self::Error> {
198        match hdr_value.to_str() {
199             std::result::Result::Ok(value) => {
200                    match <Hat as std::str::FromStr>::from_str(value) {
201                        std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)),
202                        std::result::Result::Err(err) => std::result::Result::Err(
203                            format!("Unable to convert header value '{}' into Hat - {}",
204                                value, err))
205                    }
206             },
207             std::result::Result::Err(e) => std::result::Result::Err(
208                 format!("Unable to convert header: {:?} to string: {}",
209                     hdr_value, e))
210        }
211    }
212}
213
214
215#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
216#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
217pub struct Hat {
218    /// Product
219    #[serde(rename = "product")]
220    #[serde(skip_serializing_if="Option::is_none")]
221    pub product: Option<String>,
222
223    /// Product ID
224    #[serde(rename = "productId")]
225    #[serde(skip_serializing_if="Option::is_none")]
226    pub product_id: Option<String>,
227
228    /// Product Version
229    #[serde(rename = "productVer")]
230    #[serde(skip_serializing_if="Option::is_none")]
231    pub product_ver: Option<String>,
232
233    /// Hat UUID
234    #[serde(rename = "uuid")]
235    #[serde(skip_serializing_if="Option::is_none")]
236    pub uuid: Option<String>,
237
238    /// Hat Vendor
239    #[serde(rename = "vendor")]
240    #[serde(skip_serializing_if="Option::is_none")]
241    pub vendor: Option<String>,
242
243}
244
245impl Hat {
246    pub fn new() -> Hat {
247        Hat {
248            product: None,
249            product_id: None,
250            product_ver: None,
251            uuid: None,
252            vendor: None,
253        }
254    }
255}
256
257/// Converts the Hat value to the Query Parameters representation (style=form, explode=false)
258/// specified in https://swagger.io/docs/specification/serialization/
259/// Should be implemented in a serde serializer
260impl std::string::ToString for Hat {
261    fn to_string(&self) -> String {
262        let mut params: Vec<String> = vec![];
263
264        if let Some(ref product) = self.product {
265            params.push("product".to_string());
266            params.push(product.to_string());
267        }
268
269
270        if let Some(ref product_id) = self.product_id {
271            params.push("productId".to_string());
272            params.push(product_id.to_string());
273        }
274
275
276        if let Some(ref product_ver) = self.product_ver {
277            params.push("productVer".to_string());
278            params.push(product_ver.to_string());
279        }
280
281
282        if let Some(ref uuid) = self.uuid {
283            params.push("uuid".to_string());
284            params.push(uuid.to_string());
285        }
286
287
288        if let Some(ref vendor) = self.vendor {
289            params.push("vendor".to_string());
290            params.push(vendor.to_string());
291        }
292
293        params.join(",").to_string()
294    }
295}
296
297/// Converts Query Parameters representation (style=form, explode=false) to a Hat value
298/// as specified in https://swagger.io/docs/specification/serialization/
299/// Should be implemented in a serde deserializer
300impl std::str::FromStr for Hat {
301    type Err = String;
302
303    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
304        #[derive(Default)]
305        // An intermediate representation of the struct to use for parsing.
306        struct IntermediateRep {
307            pub product: Vec<String>,
308            pub product_id: Vec<String>,
309            pub product_ver: Vec<String>,
310            pub uuid: Vec<String>,
311            pub vendor: Vec<String>,
312        }
313
314        let mut intermediate_rep = IntermediateRep::default();
315
316        // Parse into intermediate representation
317        let mut string_iter = s.split(',').into_iter();
318        let mut key_result = string_iter.next();
319
320        while key_result.is_some() {
321            let val = match string_iter.next() {
322                Some(x) => x,
323                None => return std::result::Result::Err("Missing value while parsing Hat".to_string())
324            };
325
326            if let Some(key) = key_result {
327                match key {
328                    "product" => intermediate_rep.product.push(String::from_str(val).map_err(|x| format!("{}", x))?),
329                    "productId" => intermediate_rep.product_id.push(String::from_str(val).map_err(|x| format!("{}", x))?),
330                    "productVer" => intermediate_rep.product_ver.push(String::from_str(val).map_err(|x| format!("{}", x))?),
331                    "uuid" => intermediate_rep.uuid.push(String::from_str(val).map_err(|x| format!("{}", x))?),
332                    "vendor" => intermediate_rep.vendor.push(String::from_str(val).map_err(|x| format!("{}", x))?),
333                    _ => return std::result::Result::Err("Unexpected key while parsing Hat".to_string())
334                }
335            }
336
337            // Get the next key
338            key_result = string_iter.next();
339        }
340
341        // Use the intermediate representation to return the struct
342        std::result::Result::Ok(Hat {
343            product: intermediate_rep.product.into_iter().next(),
344            product_id: intermediate_rep.product_id.into_iter().next(),
345            product_ver: intermediate_rep.product_ver.into_iter().next(),
346            uuid: intermediate_rep.uuid.into_iter().next(),
347            vendor: intermediate_rep.vendor.into_iter().next(),
348        })
349    }
350}
351
352
353impl Hat {
354    /// Helper function to allow us to convert this model to an XML string.
355    /// Will panic if serialisation fails.
356    #[allow(dead_code)]
357    pub(crate) fn to_xml(&self) -> String {
358        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
359    }
360}
361
362/// Max frames to listen for
363#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
364#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
365pub struct Maxframes(i32);
366
367impl std::convert::From<i32> for Maxframes {
368    fn from(x: i32) -> Self {
369        Maxframes(x)
370    }
371}
372
373
374impl std::convert::From<Maxframes> for i32 {
375    fn from(x: Maxframes) -> Self {
376        x.0
377    }
378}
379
380impl std::ops::Deref for Maxframes {
381    type Target = i32;
382    fn deref(&self) -> &i32 {
383        &self.0
384    }
385}
386
387impl std::ops::DerefMut for Maxframes {
388    fn deref_mut(&mut self) -> &mut i32 {
389        &mut self.0
390    }
391}
392
393
394impl Maxframes {
395    /// Helper function to allow us to convert this model to an XML string.
396    /// Will panic if serialisation fails.
397    #[allow(dead_code)]
398    pub(crate) fn to_xml(&self) -> String {
399        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
400    }
401}
402
403/// M-Bus device data as an XML document
404#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
405#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
406pub struct MbusData(String);
407
408impl std::convert::From<String> for MbusData {
409    fn from(x: String) -> Self {
410        MbusData(x)
411    }
412}
413
414impl std::string::ToString for MbusData {
415    fn to_string(&self) -> String {
416       self.0.to_string()
417    }
418}
419
420impl std::str::FromStr for MbusData {
421    type Err = std::string::ParseError;
422    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
423        std::result::Result::Ok(MbusData(x.to_string()))
424    }
425}
426
427impl std::convert::From<MbusData> for String {
428    fn from(x: MbusData) -> Self {
429        x.0
430    }
431}
432
433impl std::ops::Deref for MbusData {
434    type Target = String;
435    fn deref(&self) -> &String {
436        &self.0
437    }
438}
439
440impl std::ops::DerefMut for MbusData {
441    fn deref_mut(&mut self) -> &mut String {
442        &mut self.0
443    }
444}
445
446
447impl MbusData {
448    /// Helper function to allow us to convert this model to an XML string.
449    /// Will panic if serialisation fails.
450    #[allow(dead_code)]
451    pub(crate) fn to_xml(&self) -> String {
452        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
453    }
454}
455
456/// Output of libmbus scan command
457#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
458#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
459pub struct Slaves(String);
460
461impl std::convert::From<String> for Slaves {
462    fn from(x: String) -> Self {
463        Slaves(x)
464    }
465}
466
467impl std::string::ToString for Slaves {
468    fn to_string(&self) -> String {
469       self.0.to_string()
470    }
471}
472
473impl std::str::FromStr for Slaves {
474    type Err = std::string::ParseError;
475    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
476        std::result::Result::Ok(Slaves(x.to_string()))
477    }
478}
479
480impl std::convert::From<Slaves> for String {
481    fn from(x: Slaves) -> Self {
482        x.0
483    }
484}
485
486impl std::ops::Deref for Slaves {
487    type Target = String;
488    fn deref(&self) -> &String {
489        &self.0
490    }
491}
492
493impl std::ops::DerefMut for Slaves {
494    fn deref_mut(&mut self) -> &mut String {
495        &mut self.0
496    }
497}
498
499
500impl Slaves {
501    /// Helper function to allow us to convert this model to an XML string.
502    /// Will panic if serialisation fails.
503    #[allow(dead_code)]
504    pub(crate) fn to_xml(&self) -> String {
505        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
506    }
507}
508
509/// Some error text
510#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
511#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
512pub struct TextError(String);
513
514impl std::convert::From<String> for TextError {
515    fn from(x: String) -> Self {
516        TextError(x)
517    }
518}
519
520impl std::string::ToString for TextError {
521    fn to_string(&self) -> String {
522       self.0.to_string()
523    }
524}
525
526impl std::str::FromStr for TextError {
527    type Err = std::string::ParseError;
528    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
529        std::result::Result::Ok(TextError(x.to_string()))
530    }
531}
532
533impl std::convert::From<TextError> for String {
534    fn from(x: TextError) -> Self {
535        x.0
536    }
537}
538
539impl std::ops::Deref for TextError {
540    type Target = String;
541    fn deref(&self) -> &String {
542        &self.0
543    }
544}
545
546impl std::ops::DerefMut for TextError {
547    fn deref_mut(&mut self) -> &mut String {
548        &mut self.0
549    }
550}
551
552
553impl TextError {
554    /// Helper function to allow us to convert this model to an XML string.
555    /// Will panic if serialisation fails.
556    #[allow(dead_code)]
557    pub(crate) fn to_xml(&self) -> String {
558        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
559    }
560}
561
562/// A YAML file
563#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)]
564#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))]
565pub struct Yaml(String);
566
567impl std::convert::From<String> for Yaml {
568    fn from(x: String) -> Self {
569        Yaml(x)
570    }
571}
572
573impl std::string::ToString for Yaml {
574    fn to_string(&self) -> String {
575       self.0.to_string()
576    }
577}
578
579impl std::str::FromStr for Yaml {
580    type Err = std::string::ParseError;
581    fn from_str(x: &str) -> std::result::Result<Self, Self::Err> {
582        std::result::Result::Ok(Yaml(x.to_string()))
583    }
584}
585
586impl std::convert::From<Yaml> for String {
587    fn from(x: Yaml) -> Self {
588        x.0
589    }
590}
591
592impl std::ops::Deref for Yaml {
593    type Target = String;
594    fn deref(&self) -> &String {
595        &self.0
596    }
597}
598
599impl std::ops::DerefMut for Yaml {
600    fn deref_mut(&mut self) -> &mut String {
601        &mut self.0
602    }
603}
604
605
606impl Yaml {
607    /// Helper function to allow us to convert this model to an XML string.
608    /// Will panic if serialisation fails.
609    #[allow(dead_code)]
610    pub(crate) fn to_xml(&self) -> String {
611        serde_xml_rs::to_string(&self).expect("impossible to fail to serialize")
612    }
613}