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.
  • #[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)]
#[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]
);

/// 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.