1use std::fmt::Debug;
2
3pub use tokio_modbus::{Address, Quantity};
4
5pub type Word = u16;
7
8#[derive(Debug)]
9pub struct WordsCountError {}
10
11pub trait Decode: Sized {
13 fn from_be_words(words: &[Word]) -> Result<Self, WordsCountError>;
14 fn from_le_words(words: &[Word]) -> Result<Self, WordsCountError>;
15}
16
17macro_rules! impl_decode {
18 ($num_type:ty) => {
19 impl Decode for $num_type {
20 fn from_be_words(words: &[Word]) -> Result<Self, WordsCountError> {
21 let bytes = words
22 .iter()
23 .copied()
24 .flat_map(u16::to_be_bytes)
25 .collect::<Vec<u8>>();
26 let array = bytes.try_into().or(Err(WordsCountError {}))?;
27 Ok(<$num_type>::from_be_bytes(array))
28 }
29 fn from_le_words(_words: &[Word]) -> Result<Self, WordsCountError> {
30 todo!()
31 }
32 }
33 };
34}
35
36impl_decode!(i16);
37impl_decode!(i32);
38impl_decode!(i64);
39impl_decode!(u16);
40impl_decode!(u32);
41impl_decode!(u64);
42impl_decode!(f32);
43impl_decode!(f64);
44
45pub trait Encode {
47 fn to_be_words(self) -> Vec<Word>;
48 fn to_le_words(self) -> Vec<Word>;
49}
50
51macro_rules! impl_encode {
52 ($num_type:ty) => {
53 impl Encode for $num_type {
54 fn to_be_words(self) -> Vec<Word> {
55 self.to_be_bytes()
56 .chunks(2)
57 .map(|chunk| {
58 let array = chunk.try_into().expect("unexpected encoding error");
59 u16::from_be_bytes(array)
60 })
61 .collect()
62 }
63 fn to_le_words(self) -> Vec<Word> {
64 todo!()
65 }
66 }
67 };
68}
69
70impl_encode!(i16);
71impl_encode!(i32);
72impl_encode!(i64);
73impl_encode!(u16);
74impl_encode!(u32);
75impl_encode!(u64);
76impl_encode!(f32);
77impl_encode!(f64);