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,
};
pub trait PlCdrSerialize {
fn to_pl_cdr_bytes(
&self,
encoding: RepresentationIdentifier,
) -> Result<Bytes, PlCdrSerializeError>;
}
#[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<D, BO = LittleEndian>
where
BO: ByteOrder,
{
phantom: PhantomData<D>,
ghost: PhantomData<BO>,
}
impl<D, BO> no_key::SerializerAdapter<D> for PlCdrSerializerAdapter<D, BO>
where
D: PlCdrSerialize,
BO: ByteOrder,
{
type Error = PlCdrSerializeError;
fn output_encoding() -> RepresentationIdentifier {
RepresentationIdentifier::PL_CDR_LE
}
fn to_bytes(value: &D) -> Result<Bytes, Self::Error> {
value.to_pl_cdr_bytes(RepresentationIdentifier::PL_CDR_LE)
}
}
impl<D, BO> with_key::SerializerAdapter<D> for PlCdrSerializerAdapter<D, BO>
where
D: Keyed + PlCdrSerialize,
<D as Keyed>::K: PlCdrSerialize,
BO: ByteOrder,
{
fn key_to_bytes(value: &D::K) -> Result<Bytes, Self::Error> {
value.to_pl_cdr_bytes(RepresentationIdentifier::PL_CDR_LE)
}
}
pub trait PlCdrDeserialize: Sized {
fn from_pl_cdr_bytes(
input_bytes: &[u8],
encoding: RepresentationIdentifier,
) -> Result<Self, PlCdrDeserializeError>;
}
#[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<D> {
phantom: PhantomData<D>,
}
const REPR_IDS: [RepresentationIdentifier; 2] = [
RepresentationIdentifier::PL_CDR_BE,
RepresentationIdentifier::PL_CDR_LE,
];
impl<D> no_key::DeserializerAdapter<D> for PlCdrDeserializerAdapter<D>
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<D> with_key::DeserializerAdapter<D> for PlCdrDeserializerAdapter<D>
where
D: Keyed + PlCdrDeserialize,
<D as Keyed>::K: PlCdrDeserialize,
{
type DecodedKey = D::K;
fn transform_decoded_key(decoded_key: Self::DecodedKey) -> D::K {
decoded_key
}
}
impl<D> no_key::DefaultDecoder<D> for PlCdrDeserializerAdapter<D>
where
D: PlCdrDeserialize,
{
type Decoder = PlCdrDeserializer<D>;
const DECODER: Self::Decoder = PlCdrDeserializer(PhantomData);
}
impl<D> with_key::DefaultDecoder<D> for PlCdrDeserializerAdapter<D>
where
D: Keyed + PlCdrDeserialize,
D::K: PlCdrDeserialize,
{
type Decoder = PlCdrDeserializer<D>;
const DECODER: Self::Decoder = PlCdrDeserializer(PhantomData);
}
pub struct PlCdrDeserializer<D>(PhantomData<D>);
impl<D> no_key::Decode<D> for PlCdrDeserializer<D>
where
D: PlCdrDeserialize,
{
type Error = PlCdrDeserializeError;
fn decode_bytes(
self,
input_bytes: &[u8],
encoding: RepresentationIdentifier,
) -> Result<D, Self::Error> {
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<Dec, DecKey> with_key::Decode<Dec, DecKey> for PlCdrDeserializer<Dec>
where
Dec: PlCdrDeserialize,
DecKey: PlCdrDeserialize,
{
fn decode_key_bytes(
self,
input_bytes: &[u8],
encoding: RepresentationIdentifier,
) -> Result<DecKey, Self::Error> {
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<D> Clone for PlCdrDeserializer<D> {
fn clone(&self) -> Self {
Self(self.0)
}
}