TryFromBytes

Derive Macro TryFromBytes 

Source
#[derive(TryFromBytes)]
{
    // Attributes available to this derive:
    #[packbytes]
    #[packbytes_error]
    #[packbytes_error_exp]
}
Expand description

Derive the TryFromBytes trait for structs where each field implements it and fieldless enums.

Const generics in stable don’t allow implementing TryFromBytes for arrays [T; N] where T: TryFromBytes. This macro circumvents that by deriving a different implementation for fields whose types are arrays, allowing the trait to be derived even for structs with such fields. Note that before core::array::try_from_fn is stabilised, this is provided only for T: FromBytes.

§Endianness

By default, the FromBytes and ToBytes derive macros assume that the data is prefered to be stored in the little endian order. You can change this by setting the attribute #[packbytes(be)] for big endian or #[packbytes(ne)] for the platform native endian.

§Fieldless enums

The trait is implementing for fieldless enums by first converting bytes to a numerical value (of the type set by the repr attribute on the enum) and then comparing it to the values of all variants.

§Errors

By default, the error type is packbytes::errors::InvalidData. You can provide a custom error type with the packbytes_error attribute.

For enums, in case the bytes don’t represent a valid enum variant, a value of the erro provided by the Default trait (if implemented) is returned. You can overrride it by setting the packbytes_error_exp attribute for a custom error expression.

For structs, you need to make sure that your error implements From<<T as TryFromBytes>::Error> for every T which is a type of a field of the struct. In particular, the types that implement FromBytes have error type std::convert::Infallible (the conversion can never fail). Thus your error type should implement From<std::convert::Infallible>. (When the ! type is stabilised, this will automatically be true for every type.

enum MyError {
    InvalidFoo,
    SomethingElse
}

impl From<std::convert::Infallible> for MyError {
    fn from(impossible: std::convert::Infallible) -> Self {
        unreachable!()
    }
}

#[derive(TryFromBytes)]
#[packbytes_error(MyError)]
#[packbytes_error_exp(MyError::InvalidFoo)]
enum Foo {
    Bar,
    Baz
}

#[derive(TryFromBytes)]
#[packbytes_error(MyError)]
struct MyStruct {
    val: u16,
    foo: Foo
}