easy_modbus/codec/
encoder.rs

1use std::io::{Error, Result};
2
3use bytes::BytesMut;
4use tokio_util::codec::Encoder;
5
6use crate::codec::{RtuClientCodec, RtuServerCodec, TcpClientCodec};
7use crate::frame::request::*;
8use crate::frame::response::*;
9use crate::frame::response::Response;
10
11use super::TcpServerCodec;
12
13impl Encoder<Request> for RtuClientCodec {
14    type Error = Error;
15
16    fn encode(
17        &mut self,
18        item: Request,
19        dst: &mut BytesMut,
20    ) -> std::result::Result<(), Self::Error> {
21        request_to_bytesmut(item, dst);
22        Ok(())
23    }
24}
25
26impl Encoder<Response> for RtuServerCodec {
27    type Error = Error;
28
29    fn encode(
30        &mut self,
31        item: Response,
32        dst: &mut BytesMut,
33    ) -> std::result::Result<(), Self::Error> {
34        response_to_bytesmut(item, dst);
35        Ok(())
36    }
37}
38
39impl Encoder<Request> for TcpClientCodec {
40    type Error = Error;
41
42    fn encode(&mut self, item: Request, dst: &mut BytesMut) -> Result<()> {
43        request_to_bytesmut(item, dst);
44        Ok(())
45    }
46}
47
48impl Encoder<Response> for TcpServerCodec {
49    type Error = Error;
50
51    fn encode(&mut self, item: Response, dst: &mut BytesMut) -> Result<()> {
52        response_to_bytesmut(item, dst);
53        Ok(())
54    }
55}
56
57#[cfg(test)]
58mod rtu_client_encoder_test {
59    use bytes::BytesMut;
60    use tokio_util::codec::Encoder;
61
62    use crate::codec::RtuClientCodec;
63    use crate::frame::Frame;
64
65    #[test]
66    fn read_coils_request_test() {
67        let mut codec = RtuClientCodec::default();
68        let frame = Frame::rtu();
69        let request = frame.read_coils_request(0x0B, 0x001D, 0x001F);
70        let mut dst = BytesMut::new();
71        let res = codec.encode(request, &mut dst);
72        assert!(res.is_ok());
73        let vec_l = dst.to_vec();
74        let vec_r = vec![0x0B, 0x01, 0x00, 0x1D, 0x00, 0x1F, 0xED, 0x6E];
75        assert_eq!(vec_l, vec_r);
76    }
77
78    #[test]
79    fn read_discrete_inputs_request_test() {
80        let mut codec = RtuClientCodec::default();
81        let frame = Frame::rtu();
82        let request = frame.read_discrete_request(0x0B, 0x007A, 0x001C);
83        let mut dst = BytesMut::new();
84        let res = codec.encode(request, &mut dst);
85        assert!(res.is_ok());
86        let vec_l = dst.to_vec();
87        let vec_r = vec![0x0B, 0x02, 0x00, 0x7A, 0x00, 0x1C, 0x58, 0xB0];
88        assert_eq!(vec_l, vec_r);
89    }
90
91    #[test]
92    fn read_multiple_holding_registers_request_test() {
93        let mut codec = RtuClientCodec::default();
94        let frame = Frame::rtu();
95        let request = frame.read_multiple_holding_registers_request(0x0B, 0x006F, 0x0003);
96        let mut dst = BytesMut::new();
97        let res = codec.encode(request, &mut dst);
98        assert!(res.is_ok());
99        let vec_l = dst.to_vec();
100        let vec_r = vec![0x0B, 0x03, 0x00, 0x6F, 0x00, 0x03, 0x35, 0x7C];
101        assert_eq!(vec_l, vec_r);
102    }
103
104    #[test]
105    fn read_input_registers_request_test() {
106        let mut codec = RtuClientCodec::default();
107        let frame = Frame::rtu();
108        let request = frame.read_input_registers_request(0x0B, 0x000A, 0x0001);
109        let mut dst = BytesMut::new();
110        let res = codec.encode(request, &mut dst);
111        assert!(res.is_ok());
112        let vec_l = dst.to_vec();
113        let vec_r = vec![0x0B, 0x04, 0x00, 0x0A, 0x00, 0x01, 0x11, 0x62];
114        assert_eq!(vec_l, vec_r);
115    }
116
117    #[test]
118    fn write_single_coil_request_test() {
119        let mut codec = RtuClientCodec::default();
120        let frame = Frame::rtu();
121        let request = frame.write_single_coil_request(0x0B, 0x00BF, 0x0000);
122        let mut dst = BytesMut::new();
123        let res = codec.encode(request, &mut dst);
124        assert!(res.is_ok());
125        let vec_l = dst.to_vec();
126        let vec_r = vec![0x0B, 0x05, 0x00, 0xBF, 0x00, 0x00, 0xFC, 0x84];
127        assert_eq!(vec_l, vec_r);
128    }
129
130    #[test]
131    fn write_single_holding_register_request_test() {
132        let mut codec = RtuClientCodec::default();
133        let frame = Frame::rtu();
134        let request = frame.write_single_holding_register_request(0x0B, 0x0004, 0xABCD);
135        let mut dst = BytesMut::new();
136        let res = codec.encode(request, &mut dst);
137        assert!(res.is_ok());
138        let vec_l = dst.to_vec();
139        let vec_r = vec![0x0B, 0x06, 0x00, 0x04, 0xAB, 0xCD, 0x76, 0x04];
140        assert_eq!(vec_l, vec_r);
141    }
142
143    #[test]
144    fn write_multiple_coils_request_test() {
145        let mut codec = RtuClientCodec::default();
146        let frame = Frame::rtu();
147        let request = frame.write_multiple_coils_request(0x0B, 0x001B, 0x0009, vec![0x4D, 0x01]);
148        let mut dst = BytesMut::new();
149        let res = codec.encode(request, &mut dst);
150        assert!(res.is_ok());
151        let vec_l = dst.to_vec();
152        let vec_r = vec![
153            0x0B, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0x02, 0x4D, 0x01, 0x6C, 0xA7,
154        ];
155        assert_eq!(vec_l, vec_r);
156    }
157
158    #[test]
159    fn write_multiple_holding_registers_request_test() {
160        let mut codec = RtuClientCodec::default();
161        let frame = Frame::rtu();
162        let request = frame.write_multiple_holding_registers_request(
163            0x0B,
164            0x0012,
165            vec![0x0B, 0x0A, 0xC1, 0x02],
166        );
167        let mut dst = BytesMut::new();
168        let res = codec.encode(request, &mut dst);
169        assert!(res.is_ok());
170        let vec_l = dst.to_vec();
171        let vec_r = vec![
172            0x0B, 0x10, 0x00, 0x12, 0x00, 0x02, 0x04, 0x0B, 0x0A, 0xC1, 0x02, 0xA0, 0xD5,
173        ];
174        assert_eq!(vec_l, vec_r);
175    }
176}
177
178#[cfg(test)]
179mod tcp_client_decoder_test {
180    use bytes::BytesMut;
181    use tokio_util::codec::Encoder;
182
183    use crate::codec::TcpClientCodec;
184    use crate::frame::Frame;
185
186    #[test]
187    fn read_coils_request_test() {
188        let mut codec = TcpClientCodec::default();
189        let frame = Frame::tcp();
190        let request = frame.read_coils_request(0x01, 0x02, 0x08);
191        let mut dst = BytesMut::new();
192        let res = codec.encode(request, &mut dst);
193        assert!(res.is_ok());
194        let vec_l = dst.to_vec();
195        let vec_r = vec![
196            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00, 0x02, 0x00, 0x08,
197        ];
198        assert_eq!(vec_l, vec_r);
199    }
200
201    #[test]
202    fn read_discrete_inputs_request_test() {
203        let mut codec = TcpClientCodec::default();
204        let frame = Frame::tcp();
205        let request = frame.read_discrete_request(0x01, 0x0000, 0x0012);
206        let mut dst = BytesMut::new();
207        let res = codec.encode(request, &mut dst);
208        assert!(res.is_ok());
209        let vec_l = dst.to_vec();
210        let vec_r = vec![
211            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x00, 0x00, 0x00, 0x12,
212        ];
213        assert_eq!(vec_l, vec_r);
214    }
215
216    #[test]
217    fn read_multiple_holding_registers_request_test() {
218        let mut codec = TcpClientCodec::default();
219        let frame = Frame::tcp();
220        let request = frame.read_multiple_holding_registers_request(0x01, 0x0000, 0x0003);
221        let mut dst = BytesMut::new();
222        let res = codec.encode(request, &mut dst);
223        assert!(res.is_ok());
224        let vec_l = dst.to_vec();
225        let vec_r = vec![
226            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x03,
227        ];
228        assert_eq!(vec_l, vec_r);
229    }
230
231    #[test]
232    fn read_input_registers_request_test() {
233        let mut codec = TcpClientCodec::default();
234        let frame = Frame::tcp();
235        let request = frame.read_input_registers_request(0x01, 0x0002, 0x0005);
236        let mut dst = BytesMut::new();
237        let res = codec.encode(request, &mut dst);
238        assert!(res.is_ok());
239        let vec_l = dst.to_vec();
240        let vec_r = vec![
241            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x05,
242        ];
243        assert_eq!(vec_l, vec_r);
244    }
245
246    #[test]
247    fn write_single_coil_request_test() {
248        let mut codec = TcpClientCodec::default();
249        let frame = Frame::tcp();
250        let request = frame.write_single_coil_request(0x01, 0x0003, 0xFF00);
251        let mut dst = BytesMut::new();
252        let res = codec.encode(request, &mut dst);
253        assert!(res.is_ok());
254        let vec_l = dst.to_vec();
255        let vec_r = vec![
256            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x03, 0xFF, 0x00,
257        ];
258        assert_eq!(vec_l, vec_r);
259    }
260
261    #[test]
262    fn write_single_holding_register_request_test() {
263        let mut codec = TcpClientCodec::default();
264        let frame = Frame::tcp();
265        let request = frame.write_single_holding_register_request(0x01, 0x0000, 0x000A);
266        let mut dst = BytesMut::new();
267        let res = codec.encode(request, &mut dst);
268        assert!(res.is_ok());
269        let vec_l = dst.to_vec();
270        let vec_r = vec![
271            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x00, 0x00, 0x0A,
272        ];
273        assert_eq!(vec_l, vec_r);
274    }
275
276    #[test]
277    fn write_multiple_coils_request_test() {
278        let mut codec = TcpClientCodec::default();
279        let frame = Frame::tcp();
280        let request = frame.write_multiple_coils_request(0x01, 0x001B, 0x0009, vec![0x4D, 0x01]);
281        let mut dst = BytesMut::new();
282        let res = codec.encode(request, &mut dst);
283        assert!(res.is_ok());
284        let vec_l = dst.to_vec();
285        let vec_r = vec![
286            0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0x02, 0x4D,
287            0x01,
288        ];
289        assert_eq!(vec_l, vec_r);
290    }
291
292    #[test]
293    fn write_multiple_holding_registers_request_test() {
294        let mut codec = TcpClientCodec::default();
295        let frame = Frame::tcp();
296        let request =
297            frame.write_multiple_holding_registers_request(0x01, 0x0000, vec![0x00, 0x0F]);
298        let mut dst = BytesMut::new();
299        let res = codec.encode(request, &mut dst);
300        assert!(res.is_ok());
301        let vec_l = dst.to_vec();
302        let vec_r = vec![
303            0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
304            0x0F,
305        ];
306        assert_eq!(vec_l, vec_r);
307    }
308}
309
310#[cfg(test)]
311mod tcp_server_decoder_test {
312    use bytes::BytesMut;
313    use tokio_util::codec::Encoder;
314
315    use crate::{codec::TcpServerCodec, Frame};
316    use crate::frame::{Exception, Function};
317
318    #[test]
319    fn read_coils_response_test() {
320        let mut codec = TcpServerCodec::default();
321        let frame = Frame::tcp();
322        let response = frame.read_coils_response(0x01, vec![0x00, 0x01]);
323        let mut dst = BytesMut::new();
324        let res = codec.encode(response, &mut dst);
325        assert!(res.is_ok());
326        let vec_l = dst.to_vec();
327        let vec_r = vec![
328            0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x02, 0x00, 0x01,
329        ];
330        assert_eq!(vec_l, vec_r);
331    }
332
333    #[test]
334    fn read_discrete_response_test() {
335        let mut codec = TcpServerCodec::default();
336        let frame = Frame::tcp();
337        let response = frame.read_discrete_response(0x01, vec![0x01, 0x04, 0x00]);
338        let mut dst = BytesMut::new();
339        let res = codec.encode(response, &mut dst);
340        assert!(res.is_ok());
341        let vec_l = dst.to_vec();
342        let vec_r = vec![
343            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03, 0x01, 0x04, 0x00,
344        ];
345        assert_eq!(vec_l, vec_r);
346    }
347
348    #[test]
349    fn read_holding_register_response_test() {
350        let mut codec = TcpServerCodec::default();
351        let frame = Frame::tcp();
352        let response =
353            frame.read_holding_register_response(0x01, vec![0x00, 0x21, 0x00, 0x00, 0x00, 0x00]);
354        let mut dst = BytesMut::new();
355        let res = codec.encode(response, &mut dst);
356        assert!(res.is_ok());
357        let vec_l = dst.to_vec();
358        let vec_r = vec![
359            0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x03, 0x06, 0x00, 0x21, 0x00, 0x00, 0x00,
360            0x00,
361        ];
362        assert_eq!(vec_l, vec_r);
363    }
364
365    #[test]
366    fn read_input_register_response_test() {
367        let mut codec = TcpServerCodec::default();
368        let frame = Frame::tcp();
369        let response = frame.read_input_register_response(
370            0x01,
371            vec![0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
372        );
373        let mut dst = BytesMut::new();
374        let res = codec.encode(response, &mut dst);
375        assert!(res.is_ok());
376        let vec_l = dst.to_vec();
377        let vec_r = vec![
378            0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x04, 0x0A, 0x00, 0x0C, 0x00, 0x00, 0x00,
379            0x00, 0x00, 0x00, 0x00, 0x00,
380        ];
381        assert_eq!(vec_l, vec_r);
382    }
383
384    #[test]
385    fn write_single_coil_response_test() {
386        let mut codec = TcpServerCodec::default();
387        let frame = Frame::tcp();
388        let response = frame.write_single_coil_response(0x01, 0x0003, 0xFF00);
389        let mut dst = BytesMut::new();
390        let res = codec.encode(response, &mut dst);
391        assert!(res.is_ok());
392        let vec_l = dst.to_vec();
393        let vec_r = vec![
394            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x03, 0xFF, 0x00,
395        ];
396        assert_eq!(vec_l, vec_r);
397    }
398
399    #[test]
400    fn write_single_holding_register_response_test() {
401        let mut codec = TcpServerCodec::default();
402        let frame = Frame::tcp();
403        let response = frame.write_single_holding_register_response(0x01, 0x0000, 0x000A);
404        let mut dst = BytesMut::new();
405        let res = codec.encode(response, &mut dst);
406        assert!(res.is_ok());
407        let vec_l = dst.to_vec();
408        let vec_r = vec![
409            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x00, 0x00, 0x0A,
410        ];
411        assert_eq!(vec_l, vec_r);
412    }
413
414    #[test]
415    fn write_multiple_coils_response_test() {
416        let mut codec = TcpServerCodec::default();
417        let frame = Frame::tcp();
418        let response = frame.write_multiple_coils_response(0x01, 0x001B, 0x0009);
419        let mut dst = BytesMut::new();
420        let res = codec.encode(response, &mut dst);
421        assert!(res.is_ok());
422        let vec_l = dst.to_vec();
423        let vec_r = vec![
424            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x0F, 0x00, 0x1B, 0x00, 0x09,
425        ];
426        assert_eq!(vec_l, vec_r);
427    }
428
429    #[test]
430    fn write_multiple_holding_registers_response_test() {
431        let mut codec = TcpServerCodec::default();
432        let frame = Frame::tcp();
433        let response = frame.write_multiple_holding_registers_response(0x01, 0x0000, 0x0001);
434        let mut dst = BytesMut::new();
435        let res = codec.encode(response, &mut dst);
436        assert!(res.is_ok());
437        let vec_l = dst.to_vec();
438        let vec_r = vec![
439            0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01,
440        ];
441        assert_eq!(vec_l, vec_r);
442    }
443
444    #[test]
445    fn exception_response_test() {
446        let mut codec = TcpServerCodec::default();
447        let frame = Frame::tcp();
448        let response =
449            frame.exception_response(0x0A, Function::ReadCoils, Exception::IllegalDataAddress);
450        let mut dst = BytesMut::new();
451        let res = codec.encode(response, &mut dst);
452        assert!(res.is_ok());
453        let vec_l = dst.to_vec();
454        let vec_r = vec![0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x0A, 0x81, 0x02];
455        assert_eq!(vec_l, vec_r);
456    }
457}
458
459#[cfg(test)]
460mod rtu_server_decoder_test {
461    use bytes::BytesMut;
462    use tokio_util::codec::Encoder;
463
464    use crate::{codec::RtuServerCodec, Frame};
465    use crate::frame::{Exception, Function};
466
467    #[test]
468    fn read_coils_response_test() {
469        let mut codec = RtuServerCodec::default();
470        let frame = Frame::rtu();
471        let response = frame.read_coils_response(0x0B, vec![0xCD, 0x6B, 0xB2, 0x7F]);
472        let mut dst = BytesMut::new();
473        let res = codec.encode(response, &mut dst);
474        assert!(res.is_ok());
475        let vec_l = dst.to_vec();
476        let vec_r = vec![0x0B, 0x01, 0x04, 0xCD, 0x6B, 0xB2, 0x7F, 0x2B, 0xE1];
477        assert_eq!(vec_l, vec_r);
478    }
479
480    #[test]
481    fn read_discrete_response_test() {
482        let mut codec = RtuServerCodec::default();
483        let frame = Frame::rtu();
484        let response = frame.read_discrete_response(0x0B, vec![0xAC, 0xDB, 0xFB, 0x0D]);
485        let mut dst = BytesMut::new();
486        let res = codec.encode(response, &mut dst);
487        assert!(res.is_ok());
488        let vec_l = dst.to_vec();
489        let vec_r = vec![0x0B, 0x02, 0x04, 0xAC, 0xDB, 0xFB, 0x0D, 0x82, 0x7C];
490        assert_eq!(vec_l, vec_r);
491    }
492
493    #[test]
494    fn read_holding_register_response_test() {
495        let mut codec = RtuServerCodec::default();
496        let frame = Frame::rtu();
497        let response =
498            frame.read_holding_register_response(0x0B, vec![0xAE, 0x41, 0x56, 0x52, 0x43, 0x40]);
499        let mut dst = BytesMut::new();
500        let res = codec.encode(response, &mut dst);
501        assert!(res.is_ok());
502        let vec_l = dst.to_vec();
503        let vec_r = vec![
504            0x0B, 0x03, 0x06, 0xAE, 0x41, 0x56, 0x52, 0x43, 0x40, 0xFA, 0xCD,
505        ];
506        assert_eq!(vec_l, vec_r);
507    }
508
509    #[test]
510    fn read_input_register_response_test() {
511        let mut codec = RtuServerCodec::default();
512        let frame = Frame::rtu();
513        let response = frame.read_input_register_response(0x0B, vec![0x10, 0x2F]);
514        let mut dst = BytesMut::new();
515        let res = codec.encode(response, &mut dst);
516        assert!(res.is_ok());
517        let vec_l = dst.to_vec();
518        let vec_r = vec![0x0B, 0x04, 0x02, 0x10, 0x2F, 0x6D, 0x2D];
519        assert_eq!(vec_l, vec_r);
520    }
521
522    #[test]
523    fn write_single_coil_response_test() {
524        let mut codec = RtuServerCodec::default();
525        let frame = Frame::rtu();
526        let response = frame.write_single_coil_response(0x0B, 0x00BF, 0x0000);
527        let mut dst = BytesMut::new();
528        let res = codec.encode(response, &mut dst);
529        assert!(res.is_ok());
530        let vec_l = dst.to_vec();
531        let vec_r = vec![0x0B, 0x05, 0x00, 0xBF, 0x00, 0x00, 0xFC, 0x84];
532        assert_eq!(vec_l, vec_r);
533    }
534
535    #[test]
536    fn write_single_holding_register_response_test() {
537        let mut codec = RtuServerCodec::default();
538        let frame = Frame::rtu();
539        let response = frame.write_single_holding_register_response(0x0B, 0x0004, 0xABCD);
540        let mut dst = BytesMut::new();
541        let res = codec.encode(response, &mut dst);
542        assert!(res.is_ok());
543        let vec_l = dst.to_vec();
544        let vec_r = vec![0x0B, 0x006, 0x000, 0x004, 0x0AB, 0x0CD, 0x076, 0x004];
545        assert_eq!(vec_l, vec_r);
546    }
547
548    #[test]
549    fn write_multiple_coils_response_test() {
550        let mut codec = RtuServerCodec::default();
551        let frame = Frame::rtu();
552        let response = frame.write_multiple_coils_response(0x0B, 0x001B, 0x0009);
553        let mut dst = BytesMut::new();
554        let res = codec.encode(response, &mut dst);
555        assert!(res.is_ok());
556        let vec_l = dst.to_vec();
557        let vec_r = vec![0x0B, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0xE5, 0x60];
558        assert_eq!(vec_l, vec_r);
559    }
560
561    #[test]
562    fn write_multiple_holding_registers_response_test() {
563        let mut codec = RtuServerCodec::default();
564        let frame = Frame::rtu();
565        let response = frame.write_multiple_holding_registers_response(0x0B, 0x0012, 0x0002);
566        let mut dst = BytesMut::new();
567        let res = codec.encode(response, &mut dst);
568        assert!(res.is_ok());
569        let vec_l = dst.to_vec();
570        let vec_r = vec![0x0B, 0x10, 0x00, 0x12, 0x00, 0x02, 0xE1, 0x67];
571        assert_eq!(vec_l, vec_r);
572    }
573
574    #[test]
575    fn exception_response_test() {
576        let mut codec = RtuServerCodec::default();
577        let frame = Frame::rtu();
578        let response =
579            frame.exception_response(0x0A, Function::ReadCoils, Exception::IllegalDataAddress);
580        let mut dst = BytesMut::new();
581        let res = codec.encode(response, &mut dst);
582        assert!(res.is_ok());
583        let vec_l = dst.to_vec();
584        let vec_r = vec![0x0A, 0x81, 0x02, 0xB0, 0x53];
585        assert_eq!(vec_l, vec_r);
586    }
587}