rustdds/serialization/
cdr_adapters.rs

1use std::{any::TypeId, io, marker::PhantomData};
2
3use serde::{
4  de::{Deserialize, DeserializeOwned, DeserializeSeed},
5  Serialize,
6};
7use bytes::Bytes;
8use byteorder::{BigEndian, ByteOrder, LittleEndian};
9
10use crate::{
11  dds::{
12    adapters::{no_key, with_key},
13    key::Keyed,
14  },
15  RepresentationIdentifier,
16};
17pub use super::*;
18
19/// This type adapts [`CdrSerializer`] (which implements
20/// [`serde::Serializer`]) to work as a [`no_key::SerializerAdapter`] and
21/// [`with_key::SerializerAdapter`].
22///
23/// [`CdrSerializer`] cannot directly implement the trait itself, because
24/// [`CdrSerializer`] has the type parameter BO open, and the adapter needs to
25/// be bi-endian.
26pub struct CDRSerializerAdapter<D, BO = LittleEndian>
27where
28  BO: ByteOrder,
29{
30  phantom: PhantomData<D>,
31  ghost: PhantomData<BO>,
32}
33
34impl<D, BO> no_key::SerializerAdapter<D> for CDRSerializerAdapter<D, BO>
35where
36  D: Serialize,
37  BO: ByteOrder + 'static,
38{
39  type Error = Error;
40
41  fn output_encoding() -> RepresentationIdentifier {
42    if TypeId::of::<BO>() == TypeId::of::<LittleEndian>() {
43      RepresentationIdentifier::CDR_LE
44    } else if TypeId::of::<BO>() == TypeId::of::<BigEndian>() {
45      RepresentationIdentifier::CDR_BE
46    } else {
47      // The trait ByteOrder is sealed, so there are no implementations
48      // outside the byteorder package, which defines only LittleEndian
49      // and BigEndian impls.
50      // If you end up here, please explain how did you find a third implementation.
51      unreachable!()
52    }
53  }
54
55  fn to_bytes(value: &D) -> Result<Bytes> {
56    let size_estimate = std::mem::size_of_val(value) * 2; // TODO: crude estimate
57    let mut buffer: Vec<u8> = Vec::with_capacity(size_estimate);
58    to_writer::<D, BO, &mut Vec<u8>>(&mut buffer, value)?;
59    Ok(Bytes::from(buffer))
60  }
61}
62
63impl<D, BO> with_key::SerializerAdapter<D> for CDRSerializerAdapter<D, BO>
64where
65  D: Keyed + Serialize,
66  <D as Keyed>::K: Serialize,
67  BO: ByteOrder + 'static,
68{
69  fn key_to_bytes(value: &D::K) -> Result<Bytes> {
70    let size_estimate = std::mem::size_of_val(value) * 2; // TODO: crude estimate
71    let mut buffer: Vec<u8> = Vec::with_capacity(size_estimate);
72    to_writer::<D::K, BO, &mut Vec<u8>>(&mut buffer, value)?;
73    Ok(Bytes::from(buffer))
74  }
75}
76
77/// Serialize
78pub fn to_writer_with_rep_id<T, W>(
79  writer: W,
80  value: &T,
81  encoding: RepresentationIdentifier,
82) -> Result<()>
83where
84  T: Serialize,
85  W: io::Write,
86{
87  match encoding {
88    RepresentationIdentifier::CDR_LE | RepresentationIdentifier::PL_CDR_LE => {
89      to_writer::<T, LittleEndian, W>(writer, value)
90    }
91    _ => to_writer::<T, BigEndian, W>(writer, value),
92  }
93}
94
95/// This type adapts CdrDeserializer (which implements serde::Deserializer) to
96/// work as a [`with_key::DeserializerAdapter`] and
97/// [`no_key::DeserializerAdapter`].
98///
99/// CdrDeserializer cannot directly implement
100/// the trait itself, because CdrDeserializer has the type parameter BO open,
101/// and the adapter needs to be bi-endian.
102pub struct CDRDeserializerAdapter<D> {
103  phantom: PhantomData<D>,
104}
105
106const REPR_IDS: [RepresentationIdentifier; 3] = [
107  RepresentationIdentifier::CDR_BE,
108  RepresentationIdentifier::CDR_LE,
109  RepresentationIdentifier::PL_CDR_LE,
110];
111
112impl<D> no_key::DeserializerAdapter<D> for CDRDeserializerAdapter<D> {
113  type Error = Error;
114  type Decoded = D;
115
116  fn supported_encodings() -> &'static [RepresentationIdentifier] {
117    &REPR_IDS
118  }
119
120  // no transform, just the identity function
121  fn transform_decoded(decoded: Self::Decoded) -> D {
122    decoded
123  }
124}
125
126impl<D> with_key::DeserializerAdapter<D> for CDRDeserializerAdapter<D>
127where
128  D: Keyed + DeserializeOwned,
129  <D as Keyed>::K: DeserializeOwned, // Key should do this already?
130{
131  type DecodedKey = D::K;
132
133  fn transform_decoded_key(decoded_key: Self::DecodedKey) -> D::K {
134    decoded_key
135  }
136}
137
138/// A default decoder is available for all types that implement
139/// `serde::Deserialize`.
140impl<'de, D> no_key::DefaultDecoder<D> for CDRDeserializerAdapter<D>
141where
142  D: serde::Deserialize<'de>,
143{
144  type Decoder = CdrDeserializeDecoder<D>;
145  const DECODER: Self::Decoder = CdrDeserializeDecoder(PhantomData);
146}
147
148impl<D> with_key::DefaultDecoder<D> for CDRDeserializerAdapter<D>
149where
150  D: Keyed + DeserializeOwned,
151  D::K: DeserializeOwned,
152{
153  type Decoder = CdrDeserializeDecoder<D>;
154  const DECODER: Self::Decoder = CdrDeserializeDecoder(PhantomData);
155}
156
157/// Decode type based on a `serde::Deserialize` implementation.
158pub struct CdrDeserializeDecoder<D>(PhantomData<D>);
159
160impl<'de, D> no_key::Decode<D> for CdrDeserializeDecoder<D>
161where
162  D: serde::Deserialize<'de>,
163{
164  type Error = Error;
165
166  fn decode_bytes(self, input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result<D> {
167    deserialize_from_cdr_with_decoder_and_rep_id(input_bytes, encoding, PhantomData).map(|r| r.0)
168  }
169}
170
171impl<Dec, DecKey> with_key::Decode<Dec, DecKey> for CdrDeserializeDecoder<Dec>
172where
173  Dec: DeserializeOwned,
174  DecKey: DeserializeOwned,
175{
176  fn decode_key_bytes(
177    self,
178    input_key_bytes: &[u8],
179    encoding: RepresentationIdentifier,
180  ) -> Result<DecKey> {
181    deserialize_from_cdr_with_decoder_and_rep_id(input_key_bytes, encoding, PhantomData)
182      .map(|r| r.0)
183  }
184}
185
186impl<D> Clone for CdrDeserializeDecoder<D> {
187  fn clone(&self) -> Self {
188    Self(self.0)
189  }
190}
191
192/// Decode type based on a `serde::de::DeserializeSeed` implementation.
193#[derive(Clone)]
194pub struct CdrDeserializeSeedDecoder<S, SK> {
195  value_seed: S,
196  key_seed: SK,
197}
198
199impl<'de, S, SK> CdrDeserializeSeedDecoder<S, SK>
200where
201  S: serde::de::DeserializeSeed<'de>,
202  SK: serde::de::DeserializeSeed<'de>,
203{
204  pub fn new(value_seed: S, key_seed: SK) -> Self {
205    Self {
206      value_seed,
207      key_seed,
208    }
209  }
210}
211
212/// Decode type based on a [`serde::de::DeserializeSeed`]-based decoder.
213impl<'de, D, S, SK> no_key::Decode<D> for CdrDeserializeSeedDecoder<S, SK>
214where
215  S: serde::de::DeserializeSeed<'de, Value = D>,
216{
217  type Error = Error;
218
219  fn decode_bytes(self, input_bytes: &[u8], encoding: RepresentationIdentifier) -> Result<D> {
220    deserialize_from_cdr_with_decoder_and_rep_id(input_bytes, encoding, self.value_seed)
221      .map(|r| r.0)
222  }
223}
224
225impl<'de, Dec, DecKey, S, SK> with_key::Decode<Dec, DecKey> for CdrDeserializeSeedDecoder<S, SK>
226where
227  S: serde::de::DeserializeSeed<'de, Value = Dec>,
228  SK: serde::de::DeserializeSeed<'de, Value = DecKey>,
229{
230  fn decode_key_bytes(
231    self,
232    input_key_bytes: &[u8],
233    encoding: RepresentationIdentifier,
234  ) -> Result<DecKey> {
235    deserialize_from_cdr_with_decoder_and_rep_id(input_key_bytes, encoding, self.key_seed)
236      .map(|r| r.0)
237  }
238}
239
240/// Decode type using the given [`DeserializeSeed`]-based decoder.
241///
242/// Returns deserialized object. Byte count is discarded.
243pub fn deserialize_from_cdr_with_rep_id<'de, T>(
244  input_bytes: &[u8],
245  encoding: RepresentationIdentifier,
246) -> Result<(T, usize)>
247where
248  T: Deserialize<'de>,
249{
250  deserialize_from_cdr_with_decoder_and_rep_id::<PhantomData<T>>(input_bytes, encoding, PhantomData)
251}
252
253/// Decode type using the given [`DeserializeSeed`]-based decoder.
254///
255/// Returns deserialized object and byte count of stream consumed.
256pub fn deserialize_from_cdr_with_decoder_and_rep_id<'de, S>(
257  input_bytes: &[u8],
258  encoding: RepresentationIdentifier,
259  decoder: S,
260) -> Result<(S::Value, usize)>
261where
262  S: DeserializeSeed<'de>,
263{
264  match encoding {
265    RepresentationIdentifier::CDR_LE | RepresentationIdentifier::PL_CDR_LE => {
266      let mut deserializer = CdrDeserializer::<LittleEndian>::new(input_bytes);
267      Ok((
268        decoder.deserialize(&mut deserializer)?,
269        deserializer.bytes_consumed(),
270      ))
271    }
272
273    RepresentationIdentifier::CDR_BE | RepresentationIdentifier::PL_CDR_BE => {
274      let mut deserializer = CdrDeserializer::<BigEndian>::new(input_bytes);
275      Ok((
276        decoder.deserialize(&mut deserializer)?,
277        deserializer.bytes_consumed(),
278      ))
279    }
280
281    repr_id => Err(Error::Message(format!(
282      "Unknown serialization format. requested={repr_id:?}."
283    ))),
284  }
285}