pub trait MessageOption {
fn number(&self) -> u16;
#[doc(alias = "opaque")]
fn value(&self) -> &[u8];
#[doc(alias = "string")]
fn value_str(&self) -> Option<&str> {
core::str::from_utf8(self.value()).ok()
}
#[doc(alias = "uint")]
fn value_uint<U>(&self) -> Option<U>
where
U: num_traits::sign::Unsigned + num_traits::ops::bytes::FromBytes,
U::Bytes: Sized + Default,
{
let mut bufarray: U::Bytes = Default::default();
let buf = bufarray.as_mut();
let buflen = buf.len();
let val = self.value();
if val.len() > buflen {
return None;
}
buf[buflen - val.len()..].copy_from_slice(val);
Some(U::from_be_bytes(&bufarray))
}
}
pub trait WithSortedOptions: ReadableMessage {}
pub trait ReadableMessage {
type Code: crate::numbers::Code;
type MessageOption<'a>: MessageOption
where
Self: 'a;
type OptionsIter<'a>: Iterator<Item = Self::MessageOption<'a>>
where
Self: 'a;
fn code(&self) -> Self::Code;
fn options(&self) -> Self::OptionsIter<'_>;
fn payload(&self) -> &[u8];
}
pub trait MinimalWritableMessage {
type Code: crate::numbers::Code;
type OptionNumber: crate::numbers::OptionNumber;
type AddOptionError: crate::error::RenderableOnMinimal + core::fmt::Debug;
type SetPayloadError: crate::error::RenderableOnMinimal + core::fmt::Debug;
type UnionError: crate::error::RenderableOnMinimal
+ core::fmt::Debug
+ From<Self::AddOptionError>
+ From<Self::SetPayloadError>
+ From<<Self::Code as crate::numbers::Code>::Error>
+ From<<Self::OptionNumber as crate::numbers::OptionNumber>::Error>;
fn set_code(&mut self, code: Self::Code);
fn add_option(
&mut self,
number: Self::OptionNumber,
value: &[u8],
) -> Result<(), Self::AddOptionError>;
fn set_payload(&mut self, data: &[u8]) -> Result<(), Self::SetPayloadError>;
fn set_from_message<M>(&mut self, msg: &M) -> Result<(), Self::UnionError>
where
M: ReadableMessage + WithSortedOptions,
{
use crate::numbers::{Code, OptionNumber};
self.set_code(Self::Code::new(msg.code().into())?);
for opt in msg.options() {
self.add_option(Self::OptionNumber::new(opt.number())?, opt.value())?;
}
self.set_payload(msg.payload())?;
Ok(())
}
fn add_option_str(
&mut self,
number: Self::OptionNumber,
value: &str,
) -> Result<(), Self::AddOptionError> {
self.add_option(number, value.as_bytes())
}
fn add_option_uint<U: num_traits::sign::Unsigned + num_traits::ops::bytes::ToBytes>(
&mut self,
number: Self::OptionNumber,
value: U,
) -> Result<(), Self::AddOptionError> {
let value = value.to_be_bytes();
let mut value = value.as_ref();
while let Some(&0) = value.first() {
value = &value[1..];
}
self.add_option(number, value)
}
fn convert_code_error(e: <Self::Code as crate::numbers::Code>::Error) -> Self::UnionError {
Self::UnionError::from(e)
}
fn convert_option_number_error(
e: <Self::OptionNumber as crate::numbers::OptionNumber>::Error,
) -> Self::UnionError {
Self::UnionError::from(e)
}
fn convert_add_option_error(e: Self::AddOptionError) -> Self::UnionError {
Self::UnionError::from(e)
}
fn convert_set_payload_error(e: Self::SetPayloadError) -> Self::UnionError {
Self::UnionError::from(e)
}
}
pub trait MutableWritableMessage: MinimalWritableMessage {
fn available_space(&self) -> usize;
fn payload_mut_with_len(&mut self, len: usize) -> Result<&mut [u8], Self::SetPayloadError>;
fn truncate(&mut self, len: usize) -> Result<(), Self::SetPayloadError>;
fn mutate_options<F>(&mut self, callback: F)
where
F: FnMut(Self::OptionNumber, &mut [u8]);
}
pub trait SeekWritableMessage {
}