Encode

Trait Encode 

Source
pub trait Encode<Format = ()> {
    // Required method
    fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>;
}
Expand description

Types which can be encoded to storekey format.

§Format

The storekey serialization format tries to preserve ordering, before and after serialization. This means that in general when a < b then enc(a) < enc(b) when encoded with the storekey format.

This need to preserve ordering means that storekey cannot store lengths of types which have a size only known at runtime like Vec and other collections.

In order to be able to decode a type after encoding storekey needs some way to mark the end of a runtime sized type. We cannot store the length itself as a prefix, as is common with serialization formats, as that would not preserve ordering. Instead storekey uses a zero byte to mark the end of a slice. This also means that the encoding format needs to escape zero bytes if they occur when within the runtime size type. So for example if you have a Vec<u8> with values [0,1] then the first 0 will be escaped with a 1, of course this means the the second value also needs to be escaped resulting in the final encoding of 1,0,1,1,0 for the given Vec.

§Implementing Encode.

Most of the time, when using storekey, you can rely on the derive macros to correctly implement storekey format for you. Encode is also implemented for a bunch of rust collections. However sometimes it is necessary to implement Encode yourself.

Most of the time implementing Encode is pretty straight forward. For a simple struct implementing encode can be as simple as calling encode on all it’s fields in order.


struct MyStruct{
    field_a: u32,
    field_b: String,
}

impl Encode for MyStruct{
    fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>{
        Encode::<()>::encode(&self.field_a,w)?;
        Encode::<()>::encode(&self.field_b,w)?;
        Ok(())
    }
}

For enums the generall pattern is to first encode the discriminant and then encode the variant it’s fields.


enum MyEnum{
    VariantA(u32),
    VariantB(String),
}

impl Encode for MyEnum{
    fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>{
        match self {
            MyEnum::VariantA(x) => {
                // One good pattern is to avoid using 0 or 1 as a discriminant as these might need
                // to be escaped
                w.write_u8(2)?;
                Encode::<()>::encode(x,w)?;
            }
            MyEnum::VariantB(x) => {
                // One good pattern is to avoid using 0 or 1 as a discriminant as these might need
                // to be escaped
                w.write_u8(3)?;
                Encode::<()>::encode(x,w)?;
            }
        }
        Ok(())
    }
}

Finally for runtime sized types it you need to mark locations where the decoder might expect a terminator byte to happen. Doing so will cause the write to automatically escape a 0 byte if the next encoded byte happens to be one which is required to properly deserialize runtime sized types.


struct MyVec(Vec<u8>);

impl Encode for MyVec{
    fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>{
        for v in self.0.iter(){
            // Before every entry in the vector it is possible that a terminator might happen
            // as the vec could have been shorter. So we need to mark these spots so that the
            // writer knows to escape the null byte.
            w.mark_terminator();
            Encode::<()>::encode(v,w)?;
        }
        // We have finished the list so we need to mark the end.
        w.write_terminator()?;
        Ok(())
    }
}

Required Methods§

Source

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<F> Encode<F> for bool

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for char

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for f32

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for f64

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for i8

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for i16

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for i32

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for i64

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for i128

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for str

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for u8

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for u16

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for u32

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for u64

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for u128

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for String

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F> Encode<F> for Duration

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F> + ToOwned + ?Sized> Encode<F> for Cow<'_, E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F> + ?Sized> Encode<F> for &E

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F>> Encode<F> for Bound<E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F>> Encode<F> for Option<E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F>> Encode<F> for [E]

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F>> Encode<F> for Box<E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, E: Encode<F>> Encode<F> for Vec<E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, K: Encode<F>, V: Encode<F>> Encode<F> for BTreeMap<K, V>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, K: Encode<F>, V: Encode<F>, S> Encode<F> for HashMap<K, V, S>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, O: Encode<F>, E: Encode<F>> Encode<F> for Result<O, E>

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<F, T: Encode<F>, const SIZE: usize> Encode<F> for [T; SIZE]

Source§

fn encode<W: Write>(&self, w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format> Encode<Format> for ()

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>> Encode<Format> for (A,)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>, B: Encode<Format>> Encode<Format> for (A, B)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>, B: Encode<Format>, C: Encode<Format>> Encode<Format> for (A, B, C)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>, B: Encode<Format>, C: Encode<Format>, D: Encode<Format>> Encode<Format> for (A, B, C, D)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>, B: Encode<Format>, C: Encode<Format>, D: Encode<Format>, E: Encode<Format>> Encode<Format> for (A, B, C, D, E)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Source§

impl<Format, A: Encode<Format>, B: Encode<Format>, C: Encode<Format>, D: Encode<Format>, E: Encode<Format>, F: Encode<Format>> Encode<Format> for (A, B, C, D, E, F)

Source§

fn encode<W: Write>(&self, _w: &mut Writer<W>) -> Result<(), EncodeError>

Implementors§