1use crate::base::{DataValueRaw, ErrorCode, HasErrorCode};
2use crate::{
3 error, DataValueReaderExt, DataValueWriterExt, Endian,
4 ErrorCodeReaderExt, ErrorCodeWriterExt, HasFixedCommandId, IsRequest,
5 IsResponse, IsValidResponseFor, MessageExt, ReadExt, ReadFromPayload,
6 Result, TryFromResponse, WithFixedPayloadLength, WriteExt,
7};
8use std::io::{Read, Write};
9
10#[derive(Clone, Debug, PartialEq)]
11pub struct Request {
12 pub parameter_index: u16,
13 pub value: DataValueRaw,
14}
15
16impl IsRequest for Request {
17 type Response = Response;
18}
19
20impl From<Request> for super::Request {
21 fn from(m: Request) -> Self {
22 super::Request::WriteValueToParameter(m)
23 }
24}
25
26impl WithFixedPayloadLength for Request {
27 const FIXED_PAYLOAD_LENGTH: u16 =
28 u16::FIXED_PAYLOAD_LENGTH + DataValueRaw::FIXED_PAYLOAD_LENGTH;
29}
30
31impl HasFixedCommandId for Request {
32 const COMMAND_ID: u16 = 0x2814;
33}
34
35impl MessageExt for Request {
36 fn payload_length(&self) -> u16 {
37 Self::FIXED_PAYLOAD_LENGTH
38 }
39
40 fn write_payload(&self, w: &mut dyn Write) -> Result<()> {
41 w.write_u16::<Endian>(self.parameter_index)?;
42 w.write_data_value(&self.value)?;
43 Ok(())
44 }
45}
46
47impl ReadFromPayload for Request {
48 fn read_from_payload<R: Read>(
49 r: &mut R,
50 payload_length: u16,
51 ) -> Result<Self> {
52 Self::verify_payload_length(
53 payload_length,
54 "write_value_to_parameter_request",
55 )?;
56 let parameter_index = r.read_u16::<Endian>()?;
57 let value = r.read_data_value()?;
58 Ok(Self {
59 parameter_index,
60 value,
61 })
62 }
63}
64
65#[cfg(test)]
66mod test_request {
67 use super::*;
68
69 #[test]
70 fn write_to() {
71 let mut buffer = Vec::new();
72 let options: u8 = 0x45;
73 let sequence: u8 = 0x93;
74
75 let message = Request {
76 parameter_index: 0x3344,
77 value: 0x42u64.into(),
78 };
79 message.write_to(&mut buffer, options, sequence).unwrap();
80 assert_eq!(
81 buffer,
82 [
83 0x45, 0x93, 0x14, 0x28, 0x0B, 0x00, 0x44, 0x33, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]
101 );
102 }
103 #[test]
104 fn read_from_payload() {
105 let buffer = vec![
106 0x44, 0x33, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
118 let len = buffer.len() as u16;
119 let message =
120 Request::read_from_payload(&mut buffer.as_slice(), len)
121 .unwrap();
122 assert_eq!(
123 message,
124 Request {
125 parameter_index: 0x3344,
126 value: 0x42u64.into(),
127 }
128 );
129 }
130}
131
132#[derive(Clone, Debug, PartialEq)]
133pub struct Response {
134 pub error: ErrorCode,
135}
136
137impl IsResponse for Response {
138 type Request = Request;
139}
140
141impl IsValidResponseFor for Response {
142 fn is_valid_response_for(&self, _request: &Request) -> bool {
143 true
144 }
145}
146
147impl HasErrorCode for Response {
148 fn error_code(&self) -> ErrorCode {
149 self.error
150 }
151}
152
153impl TryFromResponse for Response {
154 fn try_from_response(r: super::Response) -> Result<Self> {
155 if let super::Response::WriteValueToParameter(r) = r {
156 Ok(r)
157 } else {
158 error::UnexpectedResponseType.fail()?
159 }
160 }
161}
162
163impl From<Response> for super::Response {
164 fn from(m: Response) -> Self {
165 super::Response::WriteValueToParameter(m)
166 }
167}
168
169impl WithFixedPayloadLength for Response {
170 const FIXED_PAYLOAD_LENGTH: u16 = ErrorCode::FIXED_PAYLOAD_LENGTH;
171}
172
173impl HasFixedCommandId for Response {
174 const COMMAND_ID: u16 = 0x2815;
175}
176
177impl MessageExt for Response {
178 fn payload_length(&self) -> u16 {
179 Self::FIXED_PAYLOAD_LENGTH
180 }
181
182 fn write_payload(&self, w: &mut dyn Write) -> Result<()> {
183 w.write_error_code(self.error)?;
184 Ok(())
185 }
186}
187
188impl ReadFromPayload for Response {
189 fn read_from_payload<R: Read>(
190 r: &mut R,
191 payload_length: u16,
192 ) -> Result<Self> {
193 Self::verify_payload_length(
194 payload_length,
195 "write_value_to_parameter_response",
196 )?;
197 let error = r.read_error_code()?;
198 Ok(Self { error })
199 }
200}
201
202#[cfg(test)]
203mod test_response {
204 use super::*;
205
206 #[test]
207 fn write_to() {
208 let mut buffer = Vec::new();
209 let options: u8 = 0x45;
210 let sequence: u8 = 0x93;
211
212 let message = Response {
213 error: ErrorCode::InvalidState, };
215 message.write_to(&mut buffer, options, sequence).unwrap();
216 assert_eq!(
217 buffer,
218 [
219 0x45, 0x93, 0x15, 0x28, 0x02, 0x00, 0x07, 0x01, ]
228 );
229 }
230 #[test]
231 fn read_from_payload() {
232 let buffer = vec![
233 0x07, 0x01, ];
236 let len = buffer.len() as u16;
237 let message =
238 Response::read_from_payload(&mut buffer.as_slice(), len)
239 .unwrap();
240 assert_eq!(
241 message,
242 Response {
243 error: ErrorCode::InvalidState, }
245 );
246 }
247}