open_protocol/types/
datafield.rs

1use chrono::{DateTime, Local};
2use open_protocol_codec::decode::{self, Decode, Decoder};
3use open_protocol_codec::encode::{self, Encode, Encoder};
4use crate::enums::datatype::DataType;
5
6pub trait ParseDataField<T> {
7    fn parse(&self) -> decode::Result<T>;
8}
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct DataField {
12    /// Parameter id (PID). 5 bytes, UI. The available PIDs may vary depending on the system type.
13    pub parameter_id: u32,
14    /// Length. 3 bytes, UI. Length of data value.
15    pub length: u16,
16    /// Data Type. 2 bytes, UI. Data type of the data value.
17    pub data_type: DataType,
18    /// Unit. 3 bytes, UI. Unit of the data.
19    pub unit: u16,
20    /// Step no. 4 bytes, UI. The step number for the result variable. Sent as 0000 if not relevant.
21    pub step_no: Option<u16>,
22    /// The data value.
23    pub data_value: String,
24}
25
26impl Encode for DataField {
27    fn encode(&self, encoder: &mut Encoder) -> encode::Result<()> {
28        self.parameter_id.encode_sized(encoder, 5)?;
29        self.length.encode_sized(encoder, 3)?;
30        self.data_type.encode_sized(encoder, 2)?;
31        self.unit.encode_sized(encoder, 3)?;
32        self.step_no.unwrap_or(0).encode_sized(encoder, 4)?;
33        self.data_value
34            .encode_sized(encoder, self.length as usize)?;
35        Ok(())
36    }
37}
38
39impl Decode for DataField {
40    fn decode(decoder: &mut Decoder) -> decode::Result<Self> {
41        let parameter_id = u32::decode_sized(decoder, 5)?;
42        let length = u16::decode_sized(decoder, 3)?;
43        let data_type = DataType::decode_sized(decoder, 2)?;
44        let unit = u16::decode_sized(decoder, 3)?;
45        let step_no = u16::decode_sized(decoder, 4)?;
46        let data_value = String::decode_sized(decoder, length as usize)?;
47
48        Ok(Self {
49            parameter_id,
50            length,
51            data_type,
52            unit,
53            step_no: if step_no == 0 { None } else { Some(step_no) },
54            data_value,
55        })
56    }
57}
58
59impl ParseDataField<u16> for DataField {
60    fn parse(&self) -> decode::Result<u16> {
61        if self.data_type != DataType::UnsignedInteger {
62            return Err(decode::Error::NotImplemented);
63        }
64
65        let mut decoder = Decoder::new(self.data_value.as_bytes());
66        u16::decode_sized(&mut decoder, self.length as usize)
67    }
68}
69
70impl ParseDataField<u32> for DataField {
71    fn parse(&self) -> decode::Result<u32> {
72        if self.data_type != DataType::UnsignedInteger {
73            return Err(decode::Error::NotImplemented);
74        }
75
76        let mut decoder = Decoder::new(self.data_value.as_bytes());
77        u32::decode_sized(&mut decoder, self.length as usize)
78    }
79}
80
81impl ParseDataField<u64> for DataField {
82    fn parse(&self) -> decode::Result<u64> {
83        if self.data_type != DataType::UnsignedInteger {
84            return Err(decode::Error::NotImplemented);
85        }
86
87        let mut decoder = Decoder::new(self.data_value.as_bytes());
88        u64::decode_sized(&mut decoder, self.length as usize)
89    }
90}
91
92impl ParseDataField<bool> for DataField {
93    fn parse(&self) -> decode::Result<bool> {
94        if self.data_type != DataType::Boolean {
95            return Err(decode::Error::NotImplemented);
96        }
97
98        let mut decoder = Decoder::new(self.data_value.as_bytes());
99        bool::decode_sized(&mut decoder, self.length as usize)
100    }
101}
102
103impl ParseDataField<String> for DataField {
104    fn parse(&self) -> decode::Result<String> {
105        if self.data_type != DataType::String {
106            return Err(decode::Error::NotImplemented);
107        }
108
109        Ok(self.data_value.clone())
110    }
111}
112
113impl ParseDataField<DateTime<Local>> for DataField {
114    fn parse(&self) -> decode::Result<DateTime<Local>> {
115        if self.data_type != DataType::Timestamp {
116            return Err(decode::Error::NotImplemented);
117        }
118
119        let mut decoder = Decoder::new(self.data_value.as_bytes());
120        DateTime::<Local>::decode_sized(&mut decoder, self.length as usize)
121    }
122}
123
124impl ParseDataField<Vec<u8>> for DataField {
125    fn parse(&self) -> decode::Result<Vec<u8>> {
126        match self.data_type {
127            DataType::Hexadecimal => {
128                let mut decoder = Decoder::new(self.data_value.as_bytes());
129                let num_bytes = (self.length as usize) / 2;
130                let mut bytes = Vec::with_capacity(num_bytes);
131
132                for _ in 0..num_bytes {
133                    let c1 = char::decode_sized(&mut decoder, 1)?;
134                    let c2 = char::decode_sized(&mut decoder, 1)?;
135                    let hi = c1.to_digit(16).ok_or(decode::Error::NotImplemented)?;
136                    let lo = c2.to_digit(16).ok_or(decode::Error::NotImplemented)?;
137                    bytes.push((hi * 16 + lo) as u8);
138                }
139
140                Ok(bytes)
141            },
142
143            _ => Err(decode::Error::NotImplemented),
144        }
145    }
146}
147
148#[cfg(test)]
149mod tests {
150    use super::*;
151
152    #[test]
153    fn test_decode() {
154        let packet = "0000100201001000012";
155
156        let df: DataField = decode::decode(packet.as_bytes()).unwrap();
157
158        assert_eq!(df, DataField {
159            parameter_id: 1,
160            length: 2,
161            data_type: DataType::UnsignedInteger,
162            unit: 1,
163            step_no: None,
164            data_value: "12".into()
165        });
166    }
167
168    #[test]
169    fn test_encode() {
170        let df = DataField {
171            parameter_id: 1,
172            length: 2,
173            data_type: DataType::UnsignedInteger,
174            unit: 1,
175            step_no: None,
176            data_value: "12".into()
177        };
178
179        let encoded = encode::encode(&df).unwrap();
180
181        assert_eq!(encoded, "0000100201001000012");
182    }
183
184    #[test]
185    fn test_parse_bytes() {
186        let df = DataField {
187            parameter_id: 1,
188            length: 8,
189            data_type: DataType::Hexadecimal,
190            unit: 1,
191            step_no: None,
192            data_value: "DEADBEEF".into()
193        };
194
195        let parsed: decode::Result<Vec<u8>> = df.parse();
196
197        assert_eq!(parsed, Ok(vec![0xDE, 0xAD, 0xBE, 0xEF]));
198    }
199}