#[derive(BitEncode)]
{
// Attributes available to this derive:
#[codec]
}
derive
only.Expand description
Derive the BitDecode
and BitEncode
traits.
§Scopes
#[container, enum]
enum Enum {
#[variant]
Variant {
#[field]
field: Type,
}
}
#[container, struct]
struct Struct {
#[field]
field: Type,
}
§Using Context
The ctx
and ctx_bounds
attributes can be used to specify additional
context used during codec. The context can be accessed as __ctx
, and the tag as __tag
in any
attribute macro’s <expr>
, for example in tag
.
struct Ctx {
n: u32,
}
#[derive(BitDecode, BitEncode)]
#[codec(ctx = Ctx)]
pub struct WithElementsLength {
pub count: u32,
pub foo: bool,
#[codec(tag = count * __ctx.n)]
pub data: Vec<u32>,
}
§Attributes
Attribute | Scope | Applicability |
---|---|---|
discriminant_type | enum | rw |
discriminant | variant | rw |
bits | field, enum | rw |
flexible_array_member | field | rw |
tag | field | rw |
tag_type | field | rw |
write_value | field | w |
ctx | container | rw |
ctx_bounds | container | rw |
default | field | r |
pad_before | field, struct | rw |
pad_after | field, struct | rw |
magic | field, struct | rw |
§discriminant_type
#[codec(discriminant_type = <type>)]
Specify if enum variant should be determined by a string or interger representation of its discriminant.
#[derive(BitDecode, BitEncode)]
#[codec(discriminant_type = u8)]
enum Example {
Variant1 = 1,
Variant5 = 5,
}
§discriminant
#[codec(discriminant = <value>)]
<value>
: unique value of the discriminant’s type
#[derive(BitDecode, BitEncode)]
#[codec(discriminant_type = u8)]
enum Example {
#[codec(discriminant = 1)]
Variant1,
Variant5 = 5,
}
Specify the discriminant for a variant.
§bits
#[codec(bits = <width>)]
Determine width of field in bits.
WARNING: Bitfields disregard endianness and instead have the same endianness as the
underlying BitRead
/ BitWrite
instance. If you’re using bitfields, you almost always
want a big endian stream.
#[derive(BitDecode, BitEncode)]
struct Nibble(#[codec(bits = 4)] u8);
§flexible_array_member
#[codec(flexible_array_member)]
Variable-length field is final field in container, hence lacks a length prefix and should be read until eof.
#[derive(BitDecode, BitEncode)]
struct ReadToEnd(#[codec(flexible_array_member)] Vec<u8>);
§tag
#[codec(tag = <expr>)]
<expr>
: arbitrary expression. Fields in parent container can be used without prefixing them withself
.
Specify tag of field. The tag represents a length prefix for variable-length fields, and a
boolean for Option
.
#[derive(BitDecode, BitEncode)]
pub struct WithElementsLength {
pub count: u32,
pub foo: bool,
#[codec(tag = count as usize)]
pub data: Vec<u32>,
}
§tag_type
#[codec(tag_type = <type>[, tag_value = <expr>]?[, tag_bits = <expr>]?)]
<type>
: tag’s type<expr>
: arbitrary expression. Fields in parent container should be prefixed withself
.
Specify tag of field. The tag represents a length prefix for variable-length fields, and a
boolean for Option
. The tag is placed directly before the field. The tag_value
only has
to be specified when deriving BitEncode
.
#[derive(BitDecode, BitEncode)]
pub struct WithElementsLength {
#[codec(tag_type = u16, tag_value = self.data.len() as u16, tag_bits = 13)]
pub data: Vec<u32>,
}
§write_value
#[codec(write_value = <expr>)]
<expr>
: An expression that can be coerced to the field type. Fields in parent container should be prefixed withself
.
Specify an expression that should be used as the field’s value for writing.
#[derive(BitDecode, BitEncode)]
pub struct WithElementsLengthAuto {
#[codec(write_value = self.data.len() as u32)]
pub count: u32,
pub foo: bool,
#[codec(tag = count as usize)]
pub data: Vec<u32>,
}
§ctx
#[codec(ctx = <type>)[, ctx_generics(<generic>[, <generic>]*)]?]
<type>
: The type of the context. Either a concrete type, or one of the container’s generics<generic>
: Any generics used by the context type, with optional bounds. E.g.T: Copy
for aVec<T>
context.
Specify the type of context that will be passed to codec functions.
pub struct Ctx;
pub struct NeedsCtx;
impl BitDecode<Ctx> for NeedsCtx {
fn decode<R, E>(
_read: &mut R,
_ctx: &mut Ctx,
_tag: (),
) -> bin_proto::Result<Self>
where
R: bin_proto::BitRead,
E: bin_proto::Endianness,
{
// Use ctx here
Ok(Self)
}
}
impl BitEncode<Ctx> for NeedsCtx {
fn encode<W, E>(
&self,
_write: &mut W,
_ctx: &mut Ctx,
_tag: (),
) -> bin_proto::Result<()>
where
W: bin_proto::BitWrite,
E: bin_proto::Endianness,
{
// Use ctx here
Ok(())
}
}
#[derive(BitDecode, BitEncode)]
#[codec(ctx = Ctx)]
pub struct WithCtx(NeedsCtx);
WithCtx(NeedsCtx)
.encode_bytes_ctx(bin_proto::BigEndian, &mut Ctx, ())
.unwrap();
#[derive(BitDecode, BitEncode)]
#[codec(ctx = Ctx)]
pub struct NestedCodec<Ctx, A: BitDecode<Ctx> + BitEncode<Ctx>>(A, PhantomData<Ctx>);
pub struct Ctx<'a, T: Copy>(&'a T);
#[derive(BitDecode, BitEncode)]
#[codec(ctx = Ctx<'a, T>, ctx_generics('a, T: Copy))]
pub struct WithCtx;
§ctx_bounds
#[codec(ctx_bounds(<bound>[, <bound>]*)[, ctx_generics(<generic>[, <generic>]*)]?)]
<bounds>
: Trait bounds that must be satisfied by the context<generic>
: Any generics used by the context type. E.g.'a
for a context with aFrom<&'a i32>
bound.
Specify the trait bounds of context that will be passed to codec functions.
pub trait CtxTrait {};
pub struct NeedsCtx;
impl<Ctx: CtxTrait> BitDecode<Ctx> for NeedsCtx {
fn decode<R, E>(
_read: &mut R,
_ctx: &mut Ctx,
_tag: (),
) -> bin_proto::Result<Self>
where
R: bin_proto::BitRead,
E: bin_proto::Endianness,
{
// Use ctx here
Ok(Self)
}
}
impl<Ctx: CtxTrait> BitEncode<Ctx> for NeedsCtx {
fn encode<W, E>(
&self,
_write: &mut W,
_ctx: &mut Ctx,
_tag: (),
) -> bin_proto::Result<()>
where
W: bin_proto::BitWrite,
E: bin_proto::Endianness,
{
// Use ctx here
Ok(())
}
}
#[derive(BitDecode, BitEncode)]
#[codec(ctx_bounds(CtxTrait))]
pub struct WithCtx(NeedsCtx);
#[derive(BitDecode, BitEncode)]
#[codec(ctx_bounds(From<&'a i32>), ctx_generics('a))]
pub struct WithCtx;
§default
#[codec(default)]
Use Default::default
instead of attempting to read field.
#[derive(BitDecode, BitEncode)]
pub struct Struct(#[codec(default)] u8);
§pad_before
#[codec(pad_before = <expr>)]
Insert 0 bits when writing and skip bits when reading, prior to processing the field.
#[derive(BitDecode, BitEncode)]
pub struct Struct(#[codec(pad_before = 3)] u8);
§pad_after
#[codec(pad_after = <expr>)]
Insert 0 bits when writing and skip bits when reading, after processing the field.
#[derive(BitDecode, BitEncode)]
pub struct Struct(#[codec(pad_after = 3)] u8);
§magic
#[codec(magic = <expr>)]
<expr>
: Must evaluate to&[u8; _]
Indicates that the value must be present immediately preceding the field or struct.
#[derive(BitDecode, BitEncode)]
#[codec(magic = &[0x01, 0x02, 0x03])]
pub struct Magic(#[codec(magic = b"123")] u8);