Expand description
Serializer/deserializer adapters to connect serialization to RTPS. DeserializerAdapter is used to fit serde Deserializer implementations and DataReader together.
DataReader/DataWriter cannot assume a specific serialization format, so it needs to be given as a parameter when instantiating. For WITH_KEY topics, we need to be able to (de)serialize the key in addition to data values.
Type parameter D
is the type resulting from (successful) deserialization.
Deserialization consists of two steps: decode and transform. Decode inputs a
byte slice and outputs an intermediate type Decoded
. Transform step maps
Decoded
into D
.
It is a common case that Decoded
and D
are the same and the
transform step is the identity function.
§How to implement DeserializerAdapter<D>
We call the imaginary example serialization format MyDataFormat
.
-
Define a type
MyDataFormatAdapter<D>
, that is used as a link between RustDDS and MyDataFormat decoder routines. The decoder routines may reside in a pre-existing Rust crate. The adapter type is necessary to bridge together RustDDS and MyDataFormat, because Rust’s orphan implementation rule prevents an application crate from implementing RustDDS-defined traits on types in MyDataFormat crate. -
Implement
no_key::DeserializerAdapter<D> for MyDataFormatAdapter<D>
- Define
Error
type to indicate deserialization failures - Define the
Decoded
type. - Implement
supported_encodings
function. This function defines which RTPS data encodings are decodable by this adapter. - Implement the
transform_decoded
function. - Do not implement the provided functions in this trait.
At this point, you should be all set for deserializing no_key data with run-time seed, i.e. you are required to provide a decoder function at run time, every time.
If you do not need/want provide the decoder object at every deserialization
call, and can define a deserializer that only depends on type D
, and the
incoming byte slice, then extend your MyDataFormatAdapter<D>
as
follows
- Implement
no_key::DefaultDecoder<D> for MyDataFormatAdapter<D>
- Define a type, e.g.
MyDataFormatDecoder<D>
, that implements traitno_key::Decode<Decoded>
- Implement the
decode_bytes
function to do the decoding from byte slice toDecoded
- The decoder may minimally be a struct with no actual fields, possibly
only a
PhantomData<D>
, which makes it zero size and no cost to clone. But this depends on the workings of MyDataFormat.
- Implement the
- Implement
no_key::DefaultDecoder<D> for MyDataFormatAdapter<D>
- Define the associated type
Decoder = MyDataFormatDecoder<D>
- Define a const
DECODER
as an instance ofMyDataFormatDecoder
- Define the associated type
- Implement or derive
Clone
forMyDataFormatDecoder
. The cloning should be cheap, as a new instance is needed for each deserialization operation.
Now you should be able to deserialize no_key data with a default decoder function.
If you need to handle also with_key deserialization, then we need more implementations to also handle the instance keys.
- Implement
with_key::DeserializerAdapter<D> for MyDataFormatAdapter<D>
- Define the
DecodedKey
type. - Implement the
transform_decoded_key
function.
To use a default decoder for with_key deserialization also:
- Implement
with_key::DefaultDecoder<D> for MyDataFormatAdapter<D>
- Implement also
with_key::Decode<DecodedValue, DecodedKey>
forMyDataFormatDecoder
. - One member function
decode_key_bytes
is needed. It defines how to decode a key.
Modules§
- Deserializer/Serializer adapters for
no_key
data types. - Deserializer/Serializer adapters for
with_key
data types.