use std::collections::BTreeMap;
use bytes::Bytes;
use speedy::{Context, Readable, Writable, Writer};
use crate::{
messages::submessages::elements::parameter::Parameter,
serialization::pl_cdr_adapters::PlCdrSerializeError, structure::parameter_id::ParameterId,
RepresentationIdentifier,
};
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct ParameterList {
pub parameters: Vec<Parameter>,
}
impl ParameterList {
pub fn new() -> Self {
Self::default()
}
pub fn is_empty(&self) -> bool {
self.parameters.is_empty()
}
pub fn len_serialized(&self) -> usize {
self
.parameters
.iter()
.map(|p| p.len_serialized())
.sum::<usize>()
+ SENTINEL.len_serialized()
}
pub fn push(&mut self, p: Parameter) {
self.parameters.push(p);
}
#[cfg(feature = "security")]
pub fn concat(&mut self, other_parameter_list: ParameterList) {
self.parameters = [self.parameters.clone(), other_parameter_list.parameters].concat();
}
pub fn serialize_to_bytes(&self, endianness: speedy::Endianness) -> Result<Bytes, speedy::Error> {
let b = self.write_to_vec_with_ctx(endianness)?;
Ok(Bytes::from(b))
}
pub fn to_map(&self) -> BTreeMap<ParameterId, Vec<&Parameter>> {
self.parameters.iter().fold(BTreeMap::new(), |mut m, p| {
m.entry(p.parameter_id).or_default().push(p);
m
})
}
}
const SENTINEL: Parameter = Parameter {
parameter_id: ParameterId::PID_SENTINEL,
value: vec![],
};
impl<C: Context> Writable<C> for ParameterList {
#[inline]
fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
for param in &self.parameters {
writer.write_value(param)?;
}
writer.write_value(&SENTINEL)?;
Ok(())
}
}
impl<'a, C: Context> Readable<'a, C> for ParameterList {
#[inline]
fn read_from<R: speedy::Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
let mut parameters = Self::default();
loop {
let parameter_id = ParameterId::read_from(reader)?;
let length = u16::read_from(reader)?;
if parameter_id == ParameterId::PID_SENTINEL {
return Ok(parameters);
}
parameters.parameters.push(Parameter {
parameter_id,
value: reader.read_vec(length as usize)?,
});
}
}
}
pub trait ParameterListable {
fn to_parameter_list(
&self,
encoding: RepresentationIdentifier,
) -> Result<ParameterList, PlCdrSerializeError>;
}