Skip to main content

FrameRead

Derive Macro FrameRead 

Source
#[derive(FrameRead)]
{
    // Attributes available to this derive:
    #[frame]
}
Expand description

Derives ace_uds::codec::FrameRead for a struct or enum.

§Required container attribute

#[frame(error = "UdsError")]

The error type must implement Into<DiagError>.

§Struct field attributes

§#[frame(length = "expr")]

Reads exactly expr bytes into a &'a [u8] field via take_n. The expression is emitted verbatim and must evaluate to usize. May reference any field declared before this one by name.

#[derive(FrameRead)]
#[frame(error = "UdsError")]
pub struct ReadMemoryByAddressRequest<'a> {
    pub address_and_length_format_identifier: u8,
    #[frame(length = "(address_and_length_format_identifier & 0x0F) as usize")]
    pub memory_address: &'a [u8],
    #[frame(length = "(address_and_length_format_identifier >> 4) as usize")]
    pub memory_size: &'a [u8],
}

§#[frame(read_all)]

Consumes all remaining bytes into this field. Must be the last field. Valid for &'a [u8] and Option<&'a [u8]>. Mutually exclusive with length.

#[derive(FrameRead)]
#[frame(error = "UdsError")]
pub struct ControlDTCSettingRequest<'a> {
    pub dtc_setting_type: DTCSettingType,
    #[frame(read_all)]
    pub dtc_setting_control_option_record: Option<&'a [u8]>,
}

§#[frame(skip)]

Skips this field - receives Default::default(), cursor not advanced. Cannot be combined with read_all or length.

§Field types with no attribute needed

The following types implement FrameRead and are decoded automatically without any #[frame(...)] attribute:

  • u8, u16, u32 - big-endian
  • [u8; N] - fixed-size array
  • &'a [u8] - consumes all remaining bytes (trailing field only)
  • Option<T: FrameRead> - None if empty, Some otherwise
  • FrameIter<'a, T: FrameRead> - lazy iterator over remaining bytes
  • Any type implementing FrameRead

§Enum variant attributes

§#[frame(id = "0x01")]

Exact discriminant byte. Reads one byte, matches this value, then decodes the inner type from remaining bytes. Valid for newtype and unit variants.

§#[frame(id_pat = "0x80..=0xFF")]

Range or catch-all pattern. Variant must be a u8 newtype - the raw discriminant byte is passed directly as the inner value.

#[derive(FrameRead)]
#[frame(error = "UdsError")]
pub enum DTCSettingType {
    #[frame(id = "0x01")] On,
    #[frame(id = "0x02")] Off,
    #[frame(id_pat = "0x03..=0xFF")] Reserved(u8),
}