Skip to content

New and improved library and macro API #14

Open
@DaniPopes

Description

@DaniPopes

Library API

pub trait RlpEncodable: RlpLength {
    fn rlp_encode<T: BufMut>(&self, encoder: &mut Encoder<T>);

    fn rlp_encode_raw<T: BufMut>(&self, encoder: &mut Encoder<T>);

    fn rlp_len(&self) -> usize {
        let raw_len = self.rlp_len_raw();
        length_of_length(raw_len) + raw_len
    }

    fn rlp_len_raw(&self) -> usize; // Important: no default!!
}

// Might not be needed.
// pub trait DynRlpEncodable: RlpLength { /* ... */ }
// pub trait RlpLength { /* rlp_len, rlp_len_raw */ }
// impl<T> DynRlpEncodable for T where T: RlpEncodable { /* ... */ }

pub trait RlpDecodable<'de> {
     fn rlp_decode(decoder: &mut Decoder<'de>) -> Result<Self>;

     fn rlp_decode_raw(decoder: &mut Decoder<'de>) -> Result<Self> {
          Self::rlp_decode(decoder)
     }
}

pub struct Encoder<T: BufMut> {
    out: T,
}

// `struct Rlp` is replaced with `Decoder`.
pub struct Decoder<'de> {
    buf: &'de [u8],
}

impl<'de> Decoder<'de> {
    // Methods moved from `Header` ...

    // Methods for creating errors that contain source information like byte position
}

pub struct Error {
    bytepos: usize,
    kind: ErrorKind,
}

pub enum ErrorKind {
    // Previous `enum Error` ...
}

Other, not pictured:

  • Add trait implementations for tuples, with the same behavior as structs with derived impls
    • This with the improved macro attributes should remove the need of dyn Encodable, enabling use of a generic Encoder.

Improvements:

  • trait and method names prefixed with rlp to avoid conflicts on common types
  • separate methods for "raw" encoding/decoding, meaning without header, to allow #[rlp(flatten)], see below

Derive macros

New attributes:

  • (field) #[rlp(flatten)]: encode and decode using raw
  • (container) #[rlp(tagged)]: impls for enums
    • tagged: defaults to the variant's discriminant value, or the variant can have an #[rlp(tag = <expr>)] attribute.
    • not specifying this fails, to leave room for future enum representations
  • (container) #[rlp(transparent)]: replaces the separate *Wrapper macros
    • also account for #[rlp(skip)] in field number calculation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions