Module protocol::attributes
source · [−]Expand description
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,
}