1use crate::protocol::Error;
2use embedded_io::Error as _;
3
4pub trait ReadBytesExt {
9 fn read_bytes(&mut self, buf: &mut [u8]) -> Result<(), Error>;
14
15 fn read_u8(&mut self) -> Result<u8, Error> {
20 let mut buf = [0u8; 1];
21 self.read_bytes(&mut buf)?;
22 Ok(buf[0])
23 }
24
25 fn read_i8(&mut self) -> Result<i8, Error> {
30 self.read_u8().map(u8::cast_signed)
31 }
32
33 fn read_u16_be(&mut self) -> Result<u16, Error> {
38 let mut buf = [0u8; 2];
39 self.read_bytes(&mut buf)?;
40 Ok(u16::from_be_bytes(buf))
41 }
42
43 fn read_i16_be(&mut self) -> Result<i16, Error> {
48 let mut buf = [0u8; 2];
49 self.read_bytes(&mut buf)?;
50 Ok(i16::from_be_bytes(buf))
51 }
52
53 fn read_u24_be(&mut self) -> Result<u32, Error> {
58 let mut buf = [0u8; 3];
59 self.read_bytes(&mut buf)?;
60 Ok(u32::from_be_bytes([0, buf[0], buf[1], buf[2]]))
61 }
62
63 fn read_u32_be(&mut self) -> Result<u32, Error> {
68 let mut buf = [0u8; 4];
69 self.read_bytes(&mut buf)?;
70 Ok(u32::from_be_bytes(buf))
71 }
72
73 fn read_i32_be(&mut self) -> Result<i32, Error> {
78 let mut buf = [0u8; 4];
79 self.read_bytes(&mut buf)?;
80 Ok(i32::from_be_bytes(buf))
81 }
82
83 fn read_u64_be(&mut self) -> Result<u64, Error> {
88 let mut buf = [0u8; 8];
89 self.read_bytes(&mut buf)?;
90 Ok(u64::from_be_bytes(buf))
91 }
92
93 fn read_i64_be(&mut self) -> Result<i64, Error> {
98 let mut buf = [0u8; 8];
99 self.read_bytes(&mut buf)?;
100 Ok(i64::from_be_bytes(buf))
101 }
102
103 fn read_u128_be(&mut self) -> Result<u128, Error> {
108 let mut buf = [0u8; 16];
109 self.read_bytes(&mut buf)?;
110 Ok(u128::from_be_bytes(buf))
111 }
112
113 fn read_i128_be(&mut self) -> Result<i128, Error> {
118 let mut buf = [0u8; 16];
119 self.read_bytes(&mut buf)?;
120 Ok(i128::from_be_bytes(buf))
121 }
122
123 fn read_f32_be(&mut self) -> Result<f32, Error> {
128 let mut buf = [0u8; 4];
129 self.read_bytes(&mut buf)?;
130 Ok(f32::from_be_bytes(buf))
131 }
132
133 fn read_f64_be(&mut self) -> Result<f64, Error> {
138 let mut buf = [0u8; 8];
139 self.read_bytes(&mut buf)?;
140 Ok(f64::from_be_bytes(buf))
141 }
142}
143
144impl<T: embedded_io::Read> ReadBytesExt for T {
145 fn read_bytes(&mut self, buf: &mut [u8]) -> Result<(), Error> {
146 self.read_exact(buf).map_err(|e| match e {
147 embedded_io::ReadExactError::UnexpectedEof => Error::Io(embedded_io::ErrorKind::Other),
148 embedded_io::ReadExactError::Other(e) => Error::Io(e.kind()),
149 })
150 }
151}
152
153pub trait WriteBytesExt {
158 fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Error>;
163
164 fn write_u8(&mut self, val: u8) -> Result<(), Error> {
169 self.write_bytes(&[val])
170 }
171
172 fn write_i8(&mut self, val: i8) -> Result<(), Error> {
177 self.write_bytes(&[val.cast_unsigned()])
178 }
179
180 fn write_u16_be(&mut self, val: u16) -> Result<(), Error> {
185 self.write_bytes(&val.to_be_bytes())
186 }
187
188 fn write_i16_be(&mut self, val: i16) -> Result<(), Error> {
193 self.write_bytes(&val.to_be_bytes())
194 }
195
196 fn write_u24_be(&mut self, val: u32) -> Result<(), Error> {
201 self.write_bytes(&val.to_be_bytes()[1..])
202 }
203
204 fn write_u32_be(&mut self, val: u32) -> Result<(), Error> {
209 self.write_bytes(&val.to_be_bytes())
210 }
211
212 fn write_i32_be(&mut self, val: i32) -> Result<(), Error> {
217 self.write_bytes(&val.to_be_bytes())
218 }
219
220 fn write_u64_be(&mut self, val: u64) -> Result<(), Error> {
225 self.write_bytes(&val.to_be_bytes())
226 }
227
228 fn write_i64_be(&mut self, val: i64) -> Result<(), Error> {
233 self.write_bytes(&val.to_be_bytes())
234 }
235
236 fn write_u128_be(&mut self, val: u128) -> Result<(), Error> {
241 self.write_bytes(&val.to_be_bytes())
242 }
243
244 fn write_i128_be(&mut self, val: i128) -> Result<(), Error> {
249 self.write_bytes(&val.to_be_bytes())
250 }
251
252 fn write_f32_be(&mut self, val: f32) -> Result<(), Error> {
257 self.write_bytes(&val.to_be_bytes())
258 }
259
260 fn write_f64_be(&mut self, val: f64) -> Result<(), Error> {
265 self.write_bytes(&val.to_be_bytes())
266 }
267}
268
269impl<T: embedded_io::Write> WriteBytesExt for T {
270 fn write_bytes(&mut self, buf: &[u8]) -> Result<(), Error> {
271 self.write_all(buf).map_err(|e| Error::Io(e.kind()))
272 }
273}
274
275#[cfg(test)]
276#[allow(clippy::float_cmp)]
280mod tests {
281 use super::*;
282
283 struct FailingWriter;
284
285 impl embedded_io::ErrorType for FailingWriter {
286 type Error = embedded_io::ErrorKind;
287 }
288
289 impl embedded_io::Write for FailingWriter {
290 fn write(&mut self, _buf: &[u8]) -> Result<usize, Self::Error> {
291 Err(embedded_io::ErrorKind::BrokenPipe)
292 }
293
294 fn flush(&mut self) -> Result<(), Self::Error> {
295 Ok(())
296 }
297 }
298
299 struct FailingReader;
300
301 impl embedded_io::ErrorType for FailingReader {
302 type Error = embedded_io::ErrorKind;
303 }
304
305 impl embedded_io::Read for FailingReader {
306 fn read(&mut self, _buf: &mut [u8]) -> Result<usize, Self::Error> {
307 Err(embedded_io::ErrorKind::BrokenPipe)
308 }
309 }
310
311 #[test]
314 fn write_io_error_maps_to_error_io() {
315 assert!(matches!(
316 FailingWriter.write_u8(0),
317 Err(Error::Io(embedded_io::ErrorKind::BrokenPipe))
318 ));
319 }
320
321 #[test]
322 fn read_io_error_maps_to_error_io() {
323 assert!(matches!(
324 FailingReader.read_u8(),
325 Err(Error::Io(embedded_io::ErrorKind::BrokenPipe))
326 ));
327 }
328
329 #[test]
332 fn read_u8_decodes_correctly() {
333 let buf: &[u8] = &[0xAB];
334 assert_eq!((&mut &*buf).read_u8().unwrap(), 0xAB);
335 }
336
337 #[test]
338 fn read_i8_decodes_correctly() {
339 let buf: &[u8] = &[0xFF];
340 assert_eq!((&mut &*buf).read_i8().unwrap(), -1);
341 }
342
343 #[test]
344 fn read_u16_be_decodes_correctly() {
345 let buf: &[u8] = &[0x01, 0x02];
346 assert_eq!((&mut &*buf).read_u16_be().unwrap(), 0x0102);
347 }
348
349 #[test]
350 fn read_i16_be_decodes_correctly() {
351 let buf: &[u8] = &[0xFF, 0xFE];
352 assert_eq!((&mut &*buf).read_i16_be().unwrap(), -2);
353 }
354
355 #[test]
356 fn read_u24_be_decodes_correctly() {
357 let buf: &[u8] = &[0x01, 0x02, 0x03];
358 assert_eq!((&mut &*buf).read_u24_be().unwrap(), 0x0001_0203);
359 }
360
361 #[test]
362 fn read_u32_be_decodes_correctly() {
363 let buf: &[u8] = &[0x01, 0x02, 0x03, 0x04];
364 assert_eq!((&mut &*buf).read_u32_be().unwrap(), 0x0102_0304);
365 }
366
367 #[test]
368 fn read_i32_be_decodes_correctly() {
369 let buf: &[u8] = &[0xFF, 0xFF, 0xFF, 0xFE];
370 assert_eq!((&mut &*buf).read_i32_be().unwrap(), -2);
371 }
372
373 #[test]
374 fn read_u64_be_decodes_correctly() {
375 let buf: &[u8] = &[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
376 assert_eq!((&mut &*buf).read_u64_be().unwrap(), 0x0102_0304_0506_0708);
377 }
378
379 #[test]
380 fn read_i64_be_decodes_correctly() {
381 let buf: &[u8] = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE];
382 assert_eq!((&mut &*buf).read_i64_be().unwrap(), -2);
383 }
384
385 #[test]
386 fn read_u128_be_decodes_correctly() {
387 let buf: &[u8] = &[
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x01,
390 ];
391 assert_eq!((&mut &*buf).read_u128_be().unwrap(), 1);
392 }
393
394 #[test]
395 fn read_i128_be_decodes_correctly() {
396 let buf: &[u8] = &[
397 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
398 0xFF, 0xFE,
399 ];
400 assert_eq!((&mut &*buf).read_i128_be().unwrap(), -2);
401 }
402
403 #[test]
404 fn read_f32_be_decodes_correctly() {
405 let expected: f32 = 1.0;
406 let buf = expected.to_be_bytes();
407 assert_eq!((&mut buf.as_slice()).read_f32_be().unwrap(), expected);
408 }
409
410 #[test]
411 fn read_f64_be_decodes_correctly() {
412 let expected: f64 = 1.0;
413 let buf = expected.to_be_bytes();
414 assert_eq!((&mut buf.as_slice()).read_f64_be().unwrap(), expected);
415 }
416
417 #[test]
420 fn write_u8_encodes_correctly() {
421 let mut buf = [0u8; 1];
422 buf.as_mut_slice().write_u8(0xAB).unwrap();
423 assert_eq!(buf, [0xAB]);
424 }
425
426 #[test]
427 fn write_i8_encodes_correctly() {
428 let mut buf = [0u8; 1];
429 buf.as_mut_slice().write_i8(-1).unwrap();
430 assert_eq!(buf, [0xFF]);
431 }
432
433 #[test]
434 fn write_u16_be_encodes_correctly() {
435 let mut buf = [0u8; 2];
436 buf.as_mut_slice().write_u16_be(0x0102).unwrap();
437 assert_eq!(buf, [0x01, 0x02]);
438 }
439
440 #[test]
441 fn write_i16_be_encodes_correctly() {
442 let mut buf = [0u8; 2];
443 buf.as_mut_slice().write_i16_be(-2).unwrap();
444 assert_eq!(buf, [0xFF, 0xFE]);
445 }
446
447 #[test]
448 fn write_u24_be_encodes_correctly() {
449 let mut buf = [0u8; 3];
450 buf.as_mut_slice().write_u24_be(0x0001_0203).unwrap();
451 assert_eq!(buf, [0x01, 0x02, 0x03]);
452 }
453
454 #[test]
455 fn write_u32_be_encodes_correctly() {
456 let mut buf = [0u8; 4];
457 buf.as_mut_slice().write_u32_be(0x0102_0304).unwrap();
458 assert_eq!(buf, [0x01, 0x02, 0x03, 0x04]);
459 }
460
461 #[test]
462 fn write_i32_be_encodes_correctly() {
463 let mut buf = [0u8; 4];
464 buf.as_mut_slice().write_i32_be(-2).unwrap();
465 assert_eq!(buf, [0xFF, 0xFF, 0xFF, 0xFE]);
466 }
467
468 #[test]
469 fn write_u64_be_encodes_correctly() {
470 let mut buf = [0u8; 8];
471 buf.as_mut_slice()
472 .write_u64_be(0x0102_0304_0506_0708)
473 .unwrap();
474 assert_eq!(buf, [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
475 }
476
477 #[test]
478 fn write_i64_be_encodes_correctly() {
479 let mut buf = [0u8; 8];
480 buf.as_mut_slice().write_i64_be(-2).unwrap();
481 assert_eq!(buf, [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE]);
482 }
483
484 #[test]
485 fn write_u128_be_encodes_correctly() {
486 let mut buf = [0u8; 16];
487 buf.as_mut_slice().write_u128_be(1).unwrap();
488 assert_eq!(buf, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01]);
489 }
490
491 #[test]
492 fn write_i128_be_encodes_correctly() {
493 let mut buf = [0u8; 16];
494 buf.as_mut_slice().write_i128_be(-2).unwrap();
495 let expected = (-2_i128).to_be_bytes();
496 assert_eq!(buf, expected);
497 }
498
499 #[test]
500 fn write_f32_be_encodes_correctly() {
501 let val: f32 = 1.0;
502 let mut buf = [0u8; 4];
503 buf.as_mut_slice().write_f32_be(val).unwrap();
504 assert_eq!(buf, val.to_be_bytes());
505 }
506
507 #[test]
508 fn write_f64_be_encodes_correctly() {
509 let val: f64 = 1.0;
510 let mut buf = [0u8; 8];
511 buf.as_mut_slice().write_f64_be(val).unwrap();
512 assert_eq!(buf, val.to_be_bytes());
513 }
514
515 #[test]
518 fn round_trip_f32() {
519 let val: f32 = core::f32::consts::PI;
520 let mut buf = [0u8; 4];
521 buf.as_mut_slice().write_f32_be(val).unwrap();
522 assert_eq!((&mut buf.as_slice()).read_f32_be().unwrap(), val);
523 }
524
525 #[test]
526 fn round_trip_f64() {
527 let val: f64 = core::f64::consts::PI;
528 let mut buf = [0u8; 8];
529 buf.as_mut_slice().write_f64_be(val).unwrap();
530 assert_eq!((&mut buf.as_slice()).read_f64_be().unwrap(), val);
531 }
532}