embrasul_models/
types.rs

1// The ideia for the PointType trait and the implementation for decode and encode functions
2// were copied from a different crate, available at:
3// https://github.com/lukaskirner/tokio-Embrasul/blob/main/src/point.rs
4
5use crate::utils::*;
6
7pub trait PointType<T> {
8    fn decode(data: Vec<u16>) -> T;
9    fn encode(data: T) -> Vec<u16>;
10}
11
12#[derive(Debug, Clone, Copy)]
13pub struct Point<T: PointType<T>> {
14    pub name: &'static str,
15    pub offset: u16,
16    pub length: u16,
17    pub write_access: bool,
18    pub value: T,
19}
20
21impl PointType<String> for String {
22    fn decode(data: Vec<u16>) -> String {
23        let bytes: Vec<u8> = to_be_bytes(data);
24        let fbytes: Vec<u8> = bytes.iter().filter(|b| **b != 0).copied().collect();
25        String::from_utf8(fbytes).unwrap()
26    }
27
28    fn encode(data: String) -> Vec<u16> {
29        to_u16_vector(data.as_bytes())
30    }
31}
32
33impl PointType<Point<String>> for Point<String> {
34    fn decode(data: Vec<u16>) -> Point<String> {
35        let bytes: Vec<u8> = to_be_bytes(data);
36        let fbytes: Vec<u8> = bytes.iter().filter(|b| **b != 0).copied().collect();
37        let data: Point<String> = Point { name: "", offset: 0, length: 0, write_access: false, value: String::from_utf8(fbytes).unwrap() };
38        data
39    }
40
41    fn encode(data: Point<String>) -> Vec<u16> {
42        let mut regs = String::encode(data.value);
43        for _i in 0..(data.length-(regs.len() as u16)){
44            regs.push(0);
45        }
46        regs
47    }
48}
49
50impl PointType<i16> for i16 {
51    fn decode(data: Vec<u16>) -> i16 {
52        data[0] as i16
53    }
54
55    fn encode(data: i16) -> Vec<u16> {
56        vec![data as u16]
57    }
58}
59
60impl PointType<i32> for i32 {
61    fn decode(data: Vec<u16>) -> i32 {
62        let bytes = to_be_bytes(data).try_into().unwrap();
63        i32::from_be_bytes(bytes)
64    }
65
66    fn encode(data: i32) -> Vec<u16> {
67        to_u16_vector(&data.to_be_bytes())
68    }
69}
70
71impl PointType<i64> for i64 {
72    fn decode(data: Vec<u16>) -> i64 {
73        let bytes = to_be_bytes(data).try_into().unwrap();
74        i64::from_be_bytes(bytes)
75    }
76
77    fn encode(data: i64) -> Vec<u16> {
78        to_u16_vector(&data.to_be_bytes())
79    }
80}
81
82impl PointType<u16> for u16 {
83    fn decode(data: Vec<u16>) -> u16 {
84        data[0]
85    }
86
87    fn encode(data: u16) -> Vec<u16> {
88        vec![data]
89    }
90}
91
92impl PointType<u32> for u32 {
93    fn decode(data: Vec<u16>) -> u32 {
94        let bytes = to_be_bytes(data).try_into().unwrap();
95        u32::from_be_bytes(bytes)
96    }
97
98    fn encode(data: u32) -> Vec<u16> {
99        to_u16_vector(&data.to_be_bytes())
100    }
101}
102
103impl PointType<u64> for u64 {
104    fn decode(data: Vec<u16>) -> u64 {
105        let bytes = to_be_bytes(data).try_into().unwrap();
106        u64::from_be_bytes(bytes)
107    }
108
109    fn encode(data: u64) -> Vec<u16> {
110        to_u16_vector(&data.to_be_bytes())
111    }
112}
113
114impl PointType<u128> for u128 {
115    fn decode(data: Vec<u16>) -> u128 {
116        let bytes = to_be_bytes(data).try_into().unwrap();
117        u128::from_be_bytes(bytes)
118    }
119
120    fn encode(data: u128) -> Vec<u16> {
121        to_u16_vector(&data.to_be_bytes())
122    }
123}
124
125#[allow(dead_code)]
126#[cfg(feature = "md")]
127impl PointType<f32> for f32 {
128    fn decode(data: Vec<u16>) -> f32 {
129        let mut bytes: [u8; 4] = to_be_bytes(data).try_into().unwrap();
130        let tmp: [u8; 2] = [bytes[2], bytes[3]];
131        bytes[3] = bytes[1];
132        bytes[2] = bytes[0];
133        bytes[1] = tmp[1];
134        bytes[0] = tmp[0];
135        f32::from_be_bytes(bytes)
136    }
137
138    fn encode(data: f32) -> Vec<u16> {
139        let mut bytes = data.to_be_bytes();
140        let tmp: [u8; 2] = [bytes[2], bytes[3]];
141        bytes[3] = bytes[1];
142        bytes[2] = bytes[0];
143        bytes[1] = tmp[1];
144        bytes[0] = tmp[0];
145        to_u16_vector(&bytes)
146    }
147}
148
149#[allow(dead_code)]
150#[cfg(feature = "gde")]
151impl PointType<f32> for f32 {
152    fn decode(data: Vec<u16>) -> f32 {
153        let bytes: [u8; 4] = to_be_bytes(data).try_into().unwrap();
154        f32::from_be_bytes(bytes)
155    }
156
157    fn encode(data: f32) -> Vec<u16> {
158        to_u16_vector(&data.to_be_bytes())
159    }
160}
161
162#[derive(Debug, Clone)]
163pub enum EDataTypes {
164    EmbrasulString(Point<String>),
165    EmbrasulU16(Point<u16>),
166    EmbrasulU32(Point<u32>),
167    EmbrasulU64(Point<u64>),
168    EmbrasulU128(Point<u128>),
169    EmbrasulI16(Point<i16>),
170    EmbrasulI32(Point<i32>),
171    EmbrasulI64(Point<i64>),
172    EmbrasulF32(Point<f32>),
173}
174
175pub trait EmbrasulTypes {
176    // This new function acts as a constructor
177    fn new_string (data: &str) -> Self;
178    fn new_u16 (data: u16) -> Self;
179    fn new_u32 (data: u32) -> Self;
180    fn new_u64 (data: u64) -> Self;
181    fn new_u128 (data: u128) -> Self;
182    fn new_i16 (data: i16) -> Self;
183    fn new_i32 (data: i32) -> Self;
184    fn new_i64 (data: i64) -> Self;
185    fn new_f32 (data: f32) -> Self;
186}
187
188impl EmbrasulTypes for EDataTypes {
189    fn new_string (data: &str) -> EDataTypes {
190        EDataTypes::EmbrasulString(Point { name: "", offset: 0, length: 0, write_access: false, value: String::from(data) } )
191    }
192    fn new_u16 (data: u16) -> EDataTypes {
193        EDataTypes::EmbrasulU16(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
194    }
195    fn new_u32 (data: u32) -> EDataTypes {
196        EDataTypes::EmbrasulU32(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
197    }
198    fn new_u64 (data: u64) -> EDataTypes {
199        EDataTypes::EmbrasulU64(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
200    }
201    fn new_u128 (data: u128) -> EDataTypes {
202        EDataTypes::EmbrasulU128(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
203    }
204    fn new_i16 (data: i16) -> EDataTypes {
205        EDataTypes::EmbrasulI16(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
206    }
207    fn new_i32 (data: i32) -> EDataTypes {
208        EDataTypes::EmbrasulI32(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
209    }
210    fn new_i64 (data: i64) -> EDataTypes {
211        EDataTypes::EmbrasulI64(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
212    }
213    fn new_f32 (data: f32) -> EDataTypes {
214        EDataTypes::EmbrasulF32(Point { name: "", offset: 0, length: 0, write_access: false, value: data } )
215    }
216}