1use crate::Status;
4
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
6#[repr(u8)]
7pub enum DfuMode {
8 #[default]
10 Default = 0,
11 Serial = 1,
12 Uf2 = 2,
13 Ble = 3,
14}
15
16impl DfuMode {
17 pub fn parse(payload: &[u8]) -> Result<Self, Status> {
18 match payload {
19 [] | [0] => Ok(Self::Default),
20 [1] => Ok(Self::Serial),
21 [2] => Ok(Self::Uf2),
22 [3] => Ok(Self::Ble),
23 [_] => Err(Status::INVALID_ARGUMENT),
24 _ => Err(Status::PARSE_ERROR),
25 }
26 }
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32 use crate::{Frame, frame};
33
34 #[test]
35 fn optional_mode_and_invalid_payloads() {
36 let mut buf = [0; 8];
37 for mode in [
38 None,
39 Some(DfuMode::Default),
40 Some(DfuMode::Serial),
41 Some(DfuMode::Uf2),
42 Some(DfuMode::Ble),
43 ] {
44 let len = frame::dfu(&mut buf, 3, mode).unwrap();
45 let request = Frame::parse(&buf[..len]).unwrap();
46 assert_eq!(request.command(), Some(frame::Cmd::Dfu));
47 assert_eq!(request.header.tid(), 3);
48 assert_eq!(
49 DfuMode::parse(request.payload),
50 Ok(mode.unwrap_or_default())
51 );
52 assert_eq!(request.payload.len(), usize::from(mode.is_some()));
53 }
54 for value in 4..=255 {
55 assert_eq!(DfuMode::parse(&[value]), Err(Status::INVALID_ARGUMENT));
56 }
57 assert_eq!(DfuMode::parse(&[0, 0]), Err(Status::PARSE_ERROR));
58 }
59}