Crate ssz_derive

source ·
Expand description

Provides procedural derive macros for the Encode and Decode traits of the eth2_ssz crate.

§Attributes

The following struct/enum attributes are available:

  • #[ssz(enum_behaviour = "tag")]: encodes and decodes an enum with 0 fields per variant
  • #[ssz(enum_behaviour = "union")]: encodes and decodes an enum with a one-byte variant selector.
  • #[ssz(enum_behaviour = "transparent")]: allows encoding an enum by serializing only the value whilst ignoring outermost the enum. decodes by attempting to decode each variant in order and the first one that is successful is returned.
  • #[ssz(struct_behaviour = "container")]: encodes and decodes the struct as an SSZ “container”.
  • #[ssz(struct_behaviour = "transparent")]: encodes and decodes a struct with exactly one non-skipped field as if the outermost struct does not exist.

The following field attributes are available:

  • #[ssz(with = "module")]: uses the methods in module to implement ssz::Encode and ssz::Decode. This is useful when it’s not possible to create an impl for that type (e.g. the type is defined in another crate).
  • #[ssz(skip_serializing)]: this field will not be included in the serialized SSZ vector.
  • #[ssz(skip_deserializing)]: this field will not be expected in the serialized SSZ vector and it will be initialized from a Default implementation.

§Examples

§Structs

use ssz::{Encode, Decode};
use ssz_derive::{Encode, Decode};

/// Represented as an SSZ "list" wrapped in an SSZ "container".
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(struct_behaviour = "container")]   // "container" is the default behaviour
struct TypicalStruct {
    foo: Vec<u8>
}

assert_eq!(
    TypicalStruct { foo: vec![42] }.as_ssz_bytes(),
    vec![4, 0, 0, 0, 42]
);

assert_eq!(
    TypicalStruct::from_ssz_bytes(&[4, 0, 0, 0, 42]).unwrap(),
    TypicalStruct { foo: vec![42] },
);

/// Represented as an SSZ "list" *without* an SSZ "container".
#[derive(Encode, Decode)]
#[ssz(struct_behaviour = "transparent")]
struct WrapperStruct {
    foo: Vec<u8>
}

assert_eq!(
    WrapperStruct { foo: vec![42] }.as_ssz_bytes(),
    vec![42]
);

/// Represented as an SSZ "list" *without* an SSZ "container". The `bar` byte is ignored.
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(struct_behaviour = "transparent")]
struct WrapperStructSkippedField {
    foo: Vec<u8>,
    #[ssz(skip_serializing, skip_deserializing)]
    bar: u8,
}

assert_eq!(
    WrapperStructSkippedField { foo: vec![42], bar: 99 }.as_ssz_bytes(),
    vec![42]
);
assert_eq!(
    WrapperStructSkippedField::from_ssz_bytes(&[42]).unwrap(),
    WrapperStructSkippedField { foo: vec![42], bar: 0 }
);

/// Represented as an SSZ "list" *without* an SSZ "container".
#[derive(Encode, Decode)]
#[ssz(struct_behaviour = "transparent")]
struct NewType(Vec<u8>);

assert_eq!(
    NewType(vec![42]).as_ssz_bytes(),
    vec![42]
);

/// Represented as an SSZ "list" *without* an SSZ "container". The `bar` byte is ignored.
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(struct_behaviour = "transparent")]
struct NewTypeSkippedField(Vec<u8>, #[ssz(skip_serializing, skip_deserializing)] u8);

assert_eq!(
    NewTypeSkippedField(vec![42], 99).as_ssz_bytes(),
    vec![42]
);
assert_eq!(
    NewTypeSkippedField::from_ssz_bytes(&[42]).unwrap(),
    NewTypeSkippedField(vec![42], 0)
);

§Enums

use ssz::{Encode, Decode};
use ssz_derive::{Encode, Decode};

/// Represented as an SSZ "union".
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(enum_behaviour = "union")]
enum UnionEnum {
    Foo(u8),
    Bar(Vec<u8>),
}

assert_eq!(
    UnionEnum::Foo(42).as_ssz_bytes(),
    vec![0, 42]
);
assert_eq!(
    UnionEnum::from_ssz_bytes(&[1, 42, 42]).unwrap(),
    UnionEnum::Bar(vec![42, 42]),
);

/// Represented as only the value in the enum variant.
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(enum_behaviour = "transparent")]
enum TransparentEnum {
    Foo(u8),
    Bar(Vec<u8>),
}

assert_eq!(
    TransparentEnum::Foo(42).as_ssz_bytes(),
    vec![42]
);
assert_eq!(
    TransparentEnum::Bar(vec![42, 42]).as_ssz_bytes(),
    vec![42, 42]
);
assert_eq!(
    TransparentEnum::from_ssz_bytes(&[42, 42]).unwrap(),
    TransparentEnum::Bar(vec![42, 42]),
);

/// Representated as an SSZ "uint8"
#[derive(Debug, PartialEq, Encode, Decode)]
#[ssz(enum_behaviour = "tag")]
enum TagEnum {
    Foo,
    Bar,
}
assert_eq!(
   TagEnum::Foo.as_ssz_bytes(),
   vec![0]
);
assert_eq!(
   TagEnum::from_ssz_bytes(&[1]).unwrap(),
   TagEnum::Bar,
);

Derive Macros§

  • Derive ssz::Decode for a struct or enum.
  • Implements ssz::Encode for some struct or enum.