Module protocol::attributes [−][src]
Documentation about the attributes available to #[derive(Protocol)]
.
Here is an example of #[derive(Protocol)]
.
#[macro_use] extern crate protocol_derive; #[derive(Protocol)] struct Packet { version_number: u8, magic_number: u8, payload: Vec<u8>, }
Attributes that apply to items
These attributes apply to structs and enums.
#[protocol(length_prefix(<kind>(<length prefix field name>)))]
This attribute allows variable-sized fields to have their sizes specified by an arbitrary integer field in the same struct or enum.
Without this attribute, variable-sized fields default to having 32-bit unsigned integer length prefixes prefixed immediately before the field itself.
Length prefix kinds
bytes
When the length prefix type is bytes
, the length prefix
represents the total number of bytes that make up a field.
#[macro_use] extern crate protocol_derive; #[derive(Protocol)] pub struct Foo { /// This field specifes the length of the last field `reason`. /// /// When values of this type are read, the size of `reason` is /// assumed to be `reason_length` bytes. pub reason_length: u16, pub other_stuff_inbetween: [u16; 16], pub thingy: bool, /// This field #[protocol(length_prefix(bytes(reason_length)))] pub reason: String, }
elements
When the length prefix type is 'elements', the length prefix represents the number of elements in a collection or list.
#[macro_use] extern crate protocol_derive; #[derive(Protocol)] pub struct Bar { /// This field specifes the number of elements in 'data'. pub reason_length: u16, pub other_stuff_inbetween: [u16; 16], pub thingy: bool, /// This field #[protocol(length_prefix(elements(reason_length)))] pub reason: Vec<(u32, u32)>, }
Notes
This attribute can only be used with named fields. This means structs like
struct Hello(u32)
cannot be supported. This is because the length prefix
field must be specified by a name, and therefore only items with named fields
can ever have length prefixes.
Length prefixes placed different structs
It is possible for a field one one struct to specify the length of a field in another struct, so long as both structs are fields within a parent struct and the struct defining the length appears earlier than the one whose length is being described.
In this case, the length prefix field must be double quoted.
#[protocol(length_prefix(bytes("sibling_field.nested_field.value")))]
Example:
#[macro_use] extern crate protocol_derive; #[derive(Protocol)] struct Packet { /// The length of the adjacent 'reason' field is nested under this field. pub packet_header: PacketHeader, /// The length of this field is specified by the packet header. #[protocol(length_prefix(bytes("packet_header.reason_length")))] pub reason: String, } #[derive(Protocol)] pub struct PacketHeader { pub reason_length: u16, }