rustdds/dds/
adapters.rs

1//! DeserializerAdapter is used to fit serde Deserializer implementations and
2//! DataReader together.
3//!
4//! DataReader/DataWriter cannot assume a specific serialization
5//! format, so it needs to be given as a parameter when instantiating.
6//! For WITH_KEY topics, we need to be able to (de)serialize the key in addition
7//! to data values.
8//!
9//! Type parameter `D` is the type resulting from (successful) deserialization.
10//!
11//! Deserialization consists of two steps: decode and transform. Decode inputs a
12//! byte slice and outputs an intermediate type `Decoded`. Transform step maps
13//! `Decoded`into `D`.
14//!
15//! It is a common case that `Decoded` and `D` are the same and the
16//! transform step is the identity function.
17//!
18//! # How to implement `DeserializerAdapter<D>`
19//!
20//! We call the imaginary example serialization format `MyDataFormat`.
21//!
22//! 0. Define a type `MyDataFormatAdapter<D>`, that is used as a link between
23//!    RustDDS and MyDataFormat decoder routines. The decoder routines may
24//!    reside in
25//! a pre-existing Rust crate. The adapter type is
26//! necessary to bridge  together RustDDS and MyDataFormat, because Rust's
27//! orphan implementation rule prevents  an application crate from implementing
28//! RustDDS-defined traits on types in MyDataFormat crate.
29//!
30//! 1. Implement `no_key::DeserializerAdapter<D> for MyDataFormatAdapter<D>`
31//!   * Define `Error` type to indicate deserialization failures
32//!   * Define the `Decoded` type.
33//!   * Implement `supported_encodings` function. This function defines which
34//!     RTPS data encodings are decodable by this adapter.
35//!   * Implement the `transform_decoded` function.
36//!   * Do not implement the provided functions in this trait.
37//!
38//! At this point, you should be all set for deserializing no_key data with
39//! run-time seed, i.e. you are required to provide a decoder function at run
40//! time, every time.
41//!
42//! If you do not need/want provide the decoder object at every deserialization
43//! call, and can define a deserializer that only depends on type `D`, and the
44//! incoming byte slice, then extend your `MyDataFormatAdapter<D>` as
45//! follows
46//!
47//! 2. Implement `no_key::DefaultDecoder<D> for MyDataFormatAdapter<D>`
48//!   * Define a type, e.g. `MyDataFormatDecoder<D>`, that implements trait
49//!     `no_key::Decode<Decoded>`
50//!     * Implement the `decode_bytes` function to do the decoding from byte
51//!       slice to `Decoded`
52//!     * The decoder may minimally be a struct with no actual fields, possibly
53//!       only a `PhantomData<D>`, which makes it zero size and no cost to
54//!       clone. But this depends on the workings of MyDataFormat.
55//!   * Implement `no_key::DefaultDecoder<D> for MyDataFormatAdapter<D>`
56//!     * Define the associated type `Decoder = MyDataFormatDecoder<D>`
57//!     * Define a const `DECODER` as an instance of `MyDataFormatDecoder`
58//!   * Implement or derive `Clone` for `MyDataFormatDecoder`. The cloning
59//!     should be cheap, as a new instance is needed for each deserialization
60//!     operation.
61//!
62//! Now you should be able to deserialize no_key data with a default decoder
63//! function.
64//!
65//! If you need to handle also with_key deserialization, then we need more
66//! implementations to also handle the instance keys.
67//!
68//! 3. Implement `with_key::DeserializerAdapter<D> for MyDataFormatAdapter<D>`
69//!   * Define the `DecodedKey` type.
70//!   * Implement the `transform_decoded_key` function.
71//!
72//! To use a default decoder for with_key deserialization also:
73//!
74//! 4. Implement `with_key::DefaultDecoder<D> for MyDataFormatAdapter<D>`
75//!   * Implement also `with_key::Decode<DecodedValue, DecodedKey>` for
76//!     `MyDataFormatDecoder`.
77//!   * One member function `decode_key_bytes` is needed. It defines how to
78//!     decode a key.
79
80/// Deserializer/Serializer adapters for `no_key` data types.
81pub mod no_key {
82  use bytes::Bytes;
83
84  use crate::RepresentationIdentifier;
85
86  /// trait for connecting a Deserializer implementation and DataReader
87  /// together - no_key version.
88  ///
89  /// Deserialization is done in two steps: decode and transform.
90  /// The basic pipeline is:
91  ///
92  /// byte slice → decode → value of type `Self::Decoded` → call
93  /// [`Self::transform_decoded`] → value of type `D`
94  ///
95  /// The transform step may be an identity function, which means that
96  /// `Self::Decoded` and `D` are the same.
97  ///
98  /// The decoding step can be parameterized at run time, if the decoder is
99  /// defined suitaby. If there is no need for such parameterization (i.e.
100  /// decoder object), use subtrait `DefaultDecoder`, which defines decoding
101  /// that needs no decoder "seed" object at run time. In that case decoding is
102  /// dependent only on the type of the decoder and incoming byte stream.
103  pub trait DeserializerAdapter<D> {
104    /// The error type returned when decoding fails.
105    type Error: std::error::Error;
106
107    /// Type after decoding.
108    ///
109    /// The adapter might apply additional operations or wrapper types to the
110    /// decoded value, so this type might be different from `D`.
111    type Decoded;
112
113    /// Which data representations can the DeserializerAdapter read?
114    /// See RTPS specification Section 10 and Table 10.3
115    fn supported_encodings() -> &'static [RepresentationIdentifier];
116
117    /// Transform the `Self::Decoded` type returned by the decoder into a
118    /// value of type `D`.
119    ///
120    /// If [`Self::Decoded`] is set to `D`, this method can be the identity
121    /// function.
122    fn transform_decoded(decoded: Self::Decoded) -> D;
123
124    /// Deserialize data from bytes to an object using the given decoder.
125    ///
126    /// `encoding` must be something given by `supported_encodings()`, or
127    /// implementation may fail with Err or `panic!()`.
128    fn from_bytes_with<S>(
129      input_bytes: &[u8],
130      encoding: RepresentationIdentifier,
131      decoder: S,
132    ) -> Result<D, S::Error>
133    where
134      S: Decode<Self::Decoded>,
135    {
136      decoder
137        .decode_bytes(input_bytes, encoding)
138        .map(Self::transform_decoded)
139    }
140
141    /// Deserialize data from bytes to an object.
142    /// `encoding` must be something given by `supported_encodings()`, or
143    /// implementation may fail with Err or `panic!()`.
144    ///
145    /// Only usable if the adapter has a default decoder, i.e. implements
146    /// `DefaultDecoder`.
147    fn from_bytes(input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result<D, Self::Error>
148    where
149      Self: DefaultDecoder<D>,
150    {
151      Self::from_bytes_with(input_bytes, encoding, Self::DECODER)
152    }
153  }
154
155  /// The `DeserializerAdapter` can be used without a decoder object as there is
156  /// a default one.
157  pub trait DefaultDecoder<D>: DeserializerAdapter<D> {
158    /// Type of the default decoder.
159    ///
160    /// The default decoder needs to be clonable to be usable for async stream
161    /// creation (as it's needed multiple times).
162    type Decoder: Decode<Self::Decoded, Error = Self::Error> + Clone;
163
164    /// The default decoder value.
165    ///
166    /// This default decoder is typically implemented by forwarding to a
167    /// different trait, e.g. `serde::Deserialize`.
168    const DECODER: Self::Decoder;
169  }
170
171  /// The trait `Decode` defines a decoder object that produced a value of type
172  /// `Dec` from a slice of bytes and a [`RepresentationIdentifier`].
173  ///
174  /// Note
175  /// that `Decoded` maps to associated type `Decoded` in
176  /// `DeserializerAdapter` , not `D`.
177  pub trait Decode<Decoded> {
178    /// The decoding error type returned by [`Self::decode_bytes`].
179    type Error: std::error::Error;
180
181    /// Tries to decode the given byte slice to a value of type `D` using the
182    /// given encoding.
183    fn decode_bytes(
184      self,
185      input_bytes: &[u8],
186      encoding: RepresentationIdentifier,
187    ) -> Result<Decoded, Self::Error>;
188  }
189
190  /// trait for connecting a Serializer implementation and DataWriter
191  /// together - no_key version.
192  ///
193  /// This is much simpler that the Deserializer above, because any the starting
194  /// point is an application-defined type, than can be generated by any
195  /// means.
196  pub trait SerializerAdapter<D> {
197    type Error: std::error::Error; // Error type
198
199    // what encoding do we produce?
200    fn output_encoding() -> RepresentationIdentifier;
201
202    fn to_bytes(value: &D) -> Result<Bytes, Self::Error>;
203  }
204}
205
206/// Deserializer/Serializer adapters for `with_key` data types.
207pub mod with_key {
208  use bytes::Bytes;
209
210  use crate::{Keyed, RepresentationIdentifier};
211  use super::no_key;
212
213  /// trait for connecting a Deserializer implementation and DataReader
214  /// together - with_key version.
215  ///
216  /// The keyed versions inherit the no_key versions,
217  /// but here the payload type `D` implements `Keyed`, which means that thre is
218  /// an associated key type `D::K`. The `with_key` versions extend the
219  /// deserialization functionality to also handle that key type.
220  ///
221  /// `with_key` functionality is needed in DDS topics that have a key, e.g. DDS
222  /// Discovery topics. ROS 2 (as of Iron Irwini) has no concept of with_key
223  /// topics.
224  pub trait DeserializerAdapter<D>: no_key::DeserializerAdapter<D>
225  where
226    D: Keyed,
227  {
228    /// Key type after decoding and before transformation.
229    ///
230    /// The adapter might apply additional operations or wrapper types to the
231    /// decoded value, so this type might be different from `D`.
232    type DecodedKey;
233
234    /// Transform the `Self::DecodedKey` type returned by the decoder into a
235    /// value of type `D`.
236    ///
237    /// If [`Self::DecodedKey`] is set to `D`, this method can be the identity
238    /// function.
239    fn transform_decoded_key(decoded_key: Self::DecodedKey) -> D::K;
240
241    /// Deserialize data from bytes to an object using the given decoder.
242    ///
243    /// `encoding` must be something given by `supported_encodings()`, or
244    /// implementation may fail with Err or `panic!()`.
245    fn key_from_bytes_with<S>(
246      input_bytes: &[u8],
247      encoding: RepresentationIdentifier,
248      decoder: S,
249    ) -> Result<D::K, S::Error>
250    where
251      S: Decode<Self::Decoded, Self::DecodedKey>,
252    {
253      decoder
254        .decode_key_bytes(input_bytes, encoding)
255        .map(Self::transform_decoded_key)
256    }
257
258    /// Deserialize data from bytes to an object.
259    /// `encoding` must be something given by `supported_encodings()`, or
260    /// implementation may fail with Err or `panic!()`.
261    ///
262    /// Only usable if the adapter has a default decoder.
263    fn key_from_bytes(
264      input_bytes: &[u8],
265      encoding: RepresentationIdentifier,
266    ) -> Result<D::K, Self::Error>
267    where
268      Self: DefaultDecoder<D>,
269    {
270      Self::key_from_bytes_with(input_bytes, encoding, Self::DECODER)
271    }
272  }
273
274  /// The `DeserializerAdapter` can be used without a decoder object as there is
275  /// a default one. This trait defines the default.
276  pub trait DefaultDecoder<D>: DeserializerAdapter<D>
277  where
278    D: Keyed,
279  {
280    /// Type of the default decoder.
281    ///
282    /// The default decoder needs to be clonable to be usable for async stream
283    /// creation (as it's needed multiple times).
284    type Decoder: Decode<Self::Decoded, Self::DecodedKey, Error = Self::Error> + Clone;
285
286    /// The default decoder value.
287    ///
288    /// This default decoder is typically implemented by forwarding to a
289    /// different trait, e.g. `serde::Deserialize`.
290    const DECODER: Self::Decoder;
291  }
292
293  /// Decodes a value of type `Dec` from a slice of bytes and a
294  /// [`RepresentationIdentifier`]. Note that `Dec` maps to associated type
295  /// `Decoded` in `DeserializerAdapter` , not `D`.
296  pub trait Decode<Dec, DecKey>: no_key::Decode<Dec> {
297    /// Tries to decode the given byte slice to a value of type `D` using the
298    /// given encoding.
299    fn decode_key_bytes(
300      self,
301      input_key_bytes: &[u8],
302      encoding: RepresentationIdentifier,
303    ) -> Result<DecKey, Self::Error>;
304  }
305
306  /// trait for connecting a Serializer implementation and DataWriter
307  /// together - with_key version.
308  pub trait SerializerAdapter<D>: no_key::SerializerAdapter<D>
309  where
310    D: Keyed,
311  {
312    /// serialize a key `D::K` to Bytes.
313    fn key_to_bytes(value: &D::K) -> Result<Bytes, Self::Error>;
314  }
315}