Trait vector_buffers::encoding::Encodable

source ·
pub trait Encodable: Sized {
    type Metadata: AsMetadata + Copy;
    type EncodeError: Error + Send + Sync + 'static;
    type DecodeError: Error + Send + Sync + 'static;

    // Required methods
    fn get_metadata() -> Self::Metadata;
    fn can_decode(metadata: Self::Metadata) -> bool;
    fn encode<B: BufMut>(self, buffer: &mut B) -> Result<(), Self::EncodeError>;
    fn decode<B: Buf + Clone>(
        metadata: Self::Metadata,
        buffer: B,
    ) -> Result<Self, Self::DecodeError>;

    // Provided method
    fn encoded_size(&self) -> Option<usize> { ... }
}
Expand description

An object that can encode and decode itself to and from a buffer.

§Metadata

While an encoding implementation is typically fixed i.e. MyJsonEncoderType only encodes and decodes JSON, we want to provide the ability to change encodings and schemas over time without fundamentally changing all of the code in the buffer implementations.

We provide the ability to express “metadata” about the encoding implementation such that any relevant information can be included alongside the encoded object, and then passed back when decoding is required.

§Implementation

As designed, an implementor would define a primary encoding scheme, schema version, and so on, that matched how an object would be encoded. This is acquired from get_metadata by code that depends on Encodable and will be stored alongside the encoded object. When the encoded object is later read back, and the caller wants to decode it, they would also read the metadata and do two things: check that the metadata is still valid for this implementation by calling can_decode and then pass it along to the decode call itself.

§Verifying ability to decode

Calling can_decode first allows callers to check if the encoding implementation supports the parameters used to encode the given object, which provides a means to allow for versioning, schema evolution, and more. Practically speaking, an implementation might bump the version of its schema, but still support the old version for some time, and so can_decode might simply check that the metadata represents the current version of the schema, or the last version, but no other versions would be allowed. When the old version of the schema was finally removed and no longer supported, can_decode would no longer say it could decode any object whose metadata referenced that old version.

The can_decode method is provided separately, instead of being lumped together in the decode call, as a means to distinguish a lack of decoding support for a given metadata from a general decoding failure.

§Metadata-aware decoding

Likewise, the call to decode is given the metadata that was stored with the encoded object so that it knows exactly what parameters were originally used and thus how it needs approach decoding the object.

§Metadata format and meaning

Ostensibly, the metadata would represent either some sort of numeric version identifier, or could be used in a bitflags-style fashion, where each bit represents a particular piece of information: encoding type, schema version, whether specific information is present in the encoded object, and so on.

Required Associated Types§

Required Methods§

source

fn get_metadata() -> Self::Metadata

Gets the version metadata associated with this encoding scheme.

The value provided is ostensibly used as a bitfield-esque container, or potentially as a raw numeric version identifier, that identifies how a value was encoded, as well as any other information that may be necessary to successfully decode it.

source

fn can_decode(metadata: Self::Metadata) -> bool

Whether or not this encoding scheme can understand and successfully decode a value based on the given version metadata that was bundled with the value.

source

fn encode<B: BufMut>(self, buffer: &mut B) -> Result<(), Self::EncodeError>

Attempts to encode this value into the given buffer.

§Errors

If there is an error while attempting to encode this value, an error variant will be returned describing the error.

Practically speaking, based on the API, encoding errors should generally only occur if there is insufficient space in the buffer to fully encode this value. However, this is not guaranteed.

source

fn decode<B: Buf + Clone>( metadata: Self::Metadata, buffer: B, ) -> Result<Self, Self::DecodeError>

Attempts to decode an instance of this type from the given buffer and metadata.

§Errors

If there is an error while attempting to decode a value from the given buffer, or the given metadata is not valid for the implementation, an error variant will be returned describing the error.

Provided Methods§

source

fn encoded_size(&self) -> Option<usize>

Gets the encoded size, in bytes, of this value, if available.

Not all types can know ahead of time how many bytes they will occupy when encoded, hence the fallibility of this method.

Object Safety§

This trait is not object safe.

Implementors§