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§
type Metadata: AsMetadata + Copy
type EncodeError: Error + Send + Sync + 'static
type DecodeError: Error + Send + Sync + 'static
Required Methods§
sourcefn get_metadata() -> Self::Metadata
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.
sourcefn can_decode(metadata: Self::Metadata) -> bool
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.
sourcefn encode<B: BufMut>(self, buffer: &mut B) -> Result<(), Self::EncodeError>
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.
sourcefn decode<B: Buf + Clone>(
metadata: Self::Metadata,
buffer: B,
) -> Result<Self, Self::DecodeError>
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§
sourcefn encoded_size(&self) -> Option<usize>
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.