dfu 0.4.2

The core DFU library used by DFU flasher.
Documentation
use std::convert::TryFrom;
use std::fmt;
#[derive(Debug)]
pub enum DfuseCommand {
    SetAddress(u32),
    ErasePage(u32),
    MassErase,
    ReadUnprotected,
}

impl TryFrom<u8> for DfuseCommand {
    type Error = crate::error::Error;
    fn try_from(cmd: u8) -> Result<Self, crate::error::Error> {
        use crate::DfuseCommand::*;
        match cmd {
            0x21 => Ok(SetAddress(0)),
            0x41 => Ok(MassErase),
            0x92 => Ok(ReadUnprotected),
            b => Err(crate::error::Error::UnknownCommandByte(b)),
        }
    }
}

impl From<DfuseCommand> for Vec<u8> {
    fn from(command: DfuseCommand) -> Vec<u8> {
        use crate::DfuseCommand::*;
        let mut buf: Vec<u8> = Vec::new();
        let address = match command {
            SetAddress(address) => {
                buf.push(0x21);
                Some(address)
            }
            ErasePage(address) => {
                buf.push(0x41);
                Some(address)
            }
            MassErase => {
                buf.push(0x41);
                None
            }
            ReadUnprotected => {
                buf.push(0x92);
                None
            }
        };

        if let Some(address) = address {
            buf.push((address & 0xFF) as u8);
            buf.push((address >> 8) as u8);
            buf.push((address >> 16) as u8);
            buf.push((address >> 24) as u8);
        }
        buf
    }
}

impl fmt::Display for DfuseCommand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use crate::DfuseCommand::*;
        match self {
            SetAddress(_) => write!(f, "Set address"),
            ErasePage(_) | MassErase => write!(f, "Page/Mass erase"),
            ReadUnprotected => write!(f, "Read unprotected"),
        }
    }
}

mod tests {
    #[test]
    fn test_dfuse_command() {
        use crate::DfuseCommand;
        let vec = Vec::from(DfuseCommand::MassErase);
        assert_eq!(1, vec.len());
        assert_eq!(&vec![0x41], &vec);

        let vec = Vec::from(DfuseCommand::ReadUnprotected);
        assert_eq!(1, vec.len());
        assert_eq!(&vec![0x92], &vec);

        let vec = Vec::from(DfuseCommand::SetAddress(0x0801_0000));
        assert_eq!(5, vec.len());
        assert_eq!(&vec![0x21, 0x00, 0x00, 0x01, 0x08], &vec);

        let vec = Vec::from(DfuseCommand::ErasePage(0x0801_0200));
        assert_eq!(5, vec.len());
        assert_eq!(&vec![0x41, 0x00, 0x02, 0x01, 0x08], &vec);
    }
}