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}