use anyhow::anyhow;
use serde::Deserialize;
use thiserror::Error;
use super::dds::RepresentationIdentifier;
pub fn try_decode_message<'d, T: Deserialize<'d>>(msg: &'d [u8]) -> Result<T, CdrError> {
if msg.len() < 4 {
return Err(CdrError::Other(anyhow!("Invalid CDR buffer")));
}
let representation_identifier = RepresentationIdentifier::from_bytes([msg[0], msg[1]])?;
if !representation_identifier.is_cdr() && !representation_identifier.is_cdr2() {
return Err(CdrError::UnsupportedRepresentation(
representation_identifier,
));
}
if representation_identifier.is_big_endian() {
cdr_encoding::from_bytes::<T, byteorder::BigEndian>(&msg[4..])
.map(|(v, _)| v)
.map_err(CdrError::CdrEncoding)
} else {
cdr_encoding::from_bytes::<T, byteorder::LittleEndian>(&msg[4..])
.map(|(v, _)| v)
.map_err(CdrError::CdrEncoding)
}
}
#[derive(Error, Debug)]
pub enum CdrError {
#[error("Failed to deserialize CDR-encoded message: {0}")]
CdrEncoding(#[from] cdr_encoding::Error),
#[error("Failed to parse DDS message: {0}")]
Dds(#[from] super::dds::DdsError),
#[error("Message is not encoded using a CDR representation: `{0:?}`")]
UnsupportedRepresentation(RepresentationIdentifier),
#[error("{0}")]
Other(#[from] anyhow::Error),
}