pub mod coe;
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, ethercrab_wire::EtherCrabWireReadWrite)]
#[cfg_attr(test, derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
#[default]
Lowest = 0x00,
Low = 0x01,
High = 0x02,
Highest = 0x03,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, ethercrab_wire::EtherCrabWireReadWrite)]
#[cfg_attr(test, derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum MailboxType {
Err = 0x00,
Aoe = 0x01,
Eoe = 0x02,
Coe = 0x03,
Foe = 0x04,
Soe = 0x05,
VendorSpecific = 0x0f,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, ethercrab_wire::EtherCrabWireReadWrite)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[wire(bytes = 6)]
pub struct MailboxHeader {
#[wire(bytes = 2, post_skip_bytes = 2)]
pub length: u16,
#[wire(pre_skip = 6, bits = 2)]
pub priority: Priority,
#[wire(bits = 4)]
pub mailbox_type: MailboxType,
#[wire(bits = 3, post_skip = 1)]
pub counter: u8,
}
#[cfg(test)]
mod tests {
use super::*;
use arbitrary::{Arbitrary, Unstructured};
use ethercrab_wire::{EtherCrabWireRead, EtherCrabWireWriteSized};
impl<'a> Arbitrary<'a> for MailboxHeader {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
Ok(Self {
length: Arbitrary::arbitrary(u)?,
priority: Arbitrary::arbitrary(u)?,
mailbox_type: Arbitrary::arbitrary(u)?,
counter: u.choose_index(7)? as u8 + 1,
})
}
}
#[test]
#[cfg_attr(miri, ignore)]
fn mailbox_header_fuzz() {
heckcheck::check(|status: MailboxHeader| {
let packed = status.pack();
let unpacked = MailboxHeader::unpack_from_slice(&packed).expect("Unpack");
pretty_assertions::assert_eq!(status, unpacked);
Ok(())
});
}
#[test]
fn encode_header() {
let expected = [0x0a, 0x00, 0x00, 0x00, 0x00, 0x33];
let packed = MailboxHeader {
length: 10,
priority: Priority::Lowest,
counter: 3,
mailbox_type: MailboxType::Coe,
}
.pack();
assert_eq!(packed, expected);
}
#[test]
fn decode_header() {
let raw = [0x0a, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x20];
let expected = MailboxHeader {
length: 10,
priority: Priority::Lowest,
mailbox_type: MailboxType::Coe,
counter: 2,
};
let parsed = MailboxHeader::unpack_from_slice(&raw).unwrap();
assert_eq!(parsed, expected);
}
}