use std::marker::PhantomData; use bytes::Bytes; use byteorder::{ByteOrder, LittleEndian}; use crate::{ dds::adapters::{no_key, with_key}, structure::parameter_id::ParameterId, Keyed, RepresentationIdentifier, }; // This is to be implemented by all Discovery message types. // .. likely it is not useful for others. pub trait PlCdrSerialize { // encoding must be either PL_CDR_LE or PL_CDR_BE fn to_pl_cdr_bytes( &self, encoding: RepresentationIdentifier, ) -> Result; } #[derive(Debug, thiserror::Error)] pub enum PlCdrSerializeError { #[error("Serializer does not support this operation: {0}")] NotSupported(String), #[error("Speedy serializer error: {0}")] Speedy(#[from] speedy::Error), } pub struct PlCdrSerializerAdapter where BO: ByteOrder, { phantom: PhantomData, ghost: PhantomData, } impl no_key::SerializerAdapter for PlCdrSerializerAdapter where D: PlCdrSerialize, BO: ByteOrder, { type Error = PlCdrSerializeError; fn output_encoding() -> RepresentationIdentifier { // TODO: This works only for BO=LittleEndian RepresentationIdentifier::PL_CDR_LE } fn to_bytes(value: &D) -> Result { // TODO: This works only for BO=LittleEndian value.to_pl_cdr_bytes(RepresentationIdentifier::PL_CDR_LE) } } impl with_key::SerializerAdapter for PlCdrSerializerAdapter where D: Keyed + PlCdrSerialize, ::K: PlCdrSerialize, BO: ByteOrder, { fn key_to_bytes(value: &D::K) -> Result { // TODO: This works only for BO=LittleEndian value.to_pl_cdr_bytes(RepresentationIdentifier::PL_CDR_LE) } } // ---------------------------------- // ---------------------------------- // ---------------------------------- // This is to be implemented by all Discovery message types. // .. likely it is not useful for others. pub trait PlCdrDeserialize: Sized { // encoding must be either PL_CDR_LE or PL_CDR_BE fn from_pl_cdr_bytes( input_bytes: &[u8], encoding: RepresentationIdentifier, ) -> Result; } #[derive(Debug, thiserror::Error)] pub enum PlCdrDeserializeError { #[error("Deserializer does not support this operation: {0}")] NotSupported(String), #[error("Speedy deserializer error: {0}")] Speedy(#[from] speedy::Error), #[error("Parameter List missing {0:?} , expected for field {1}")] MissingField(ParameterId, String), } pub struct PlCdrDeserializerAdapter { phantom: PhantomData, } const REPR_IDS: [RepresentationIdentifier; 2] = [ // PL_CDR_* are expected RepresentationIdentifier::PL_CDR_BE, RepresentationIdentifier::PL_CDR_LE, ]; impl no_key::DeserializerAdapter for PlCdrDeserializerAdapter where D: PlCdrDeserialize, { type Error = PlCdrDeserializeError; type Decoded = D; fn supported_encodings() -> &'static [RepresentationIdentifier] { &REPR_IDS } fn transform_decoded(deserialized: Self::Decoded) -> D { deserialized } } impl with_key::DeserializerAdapter for PlCdrDeserializerAdapter where D: Keyed + PlCdrDeserialize, ::K: PlCdrDeserialize, { type DecodedKey = D::K; fn transform_decoded_key(decoded_key: Self::DecodedKey) -> D::K { decoded_key } // fn key_from_bytes( // input_bytes: &[u8], // encoding: RepresentationIdentifier, // ) -> Result { // match encoding { // RepresentationIdentifier::PL_CDR_LE | RepresentationIdentifier::PL_CDR_BE // => { ::from_pl_cdr_bytes(input_bytes, encoding) // } // repr_id => Err(PlCdrDeserializeError::NotSupported(format!( // "Unknown representation identifier {:?}", // repr_id // ))), // } // } } /// A default decoder is available if the target type implements /// [`PlCdrDeserialize`]. impl no_key::DefaultDecoder for PlCdrDeserializerAdapter where D: PlCdrDeserialize, { type Decoder = PlCdrDeserializer; const DECODER: Self::Decoder = PlCdrDeserializer(PhantomData); } impl with_key::DefaultDecoder for PlCdrDeserializerAdapter where D: Keyed + PlCdrDeserialize, D::K: PlCdrDeserialize, { type Decoder = PlCdrDeserializer; const DECODER: Self::Decoder = PlCdrDeserializer(PhantomData); } /// Decode type based on [`PlCdrDeserialize`] implementation. pub struct PlCdrDeserializer(PhantomData); impl no_key::Decode for PlCdrDeserializer where D: PlCdrDeserialize, { type Error = PlCdrDeserializeError; fn decode_bytes( self, input_bytes: &[u8], encoding: RepresentationIdentifier, ) -> Result { match encoding { RepresentationIdentifier::PL_CDR_LE | RepresentationIdentifier::PL_CDR_BE => { D::from_pl_cdr_bytes(input_bytes, encoding) } repr_id => Err(PlCdrDeserializeError::NotSupported(format!( "Unknown representation identifier {:?}", repr_id ))), } } } impl with_key::Decode for PlCdrDeserializer where Dec: PlCdrDeserialize, DecKey: PlCdrDeserialize, { fn decode_key_bytes( self, input_bytes: &[u8], encoding: RepresentationIdentifier, ) -> Result { match encoding { RepresentationIdentifier::PL_CDR_LE | RepresentationIdentifier::PL_CDR_BE => { DecKey::from_pl_cdr_bytes(input_bytes, encoding) } repr_id => Err(PlCdrDeserializeError::NotSupported(format!( "Unknown (key) representation identifier {:?}", repr_id ))), } } } impl Clone for PlCdrDeserializer { fn clone(&self) -> Self { Self(self.0) } }