#[derive(Debug, Clone)]
pub struct CoAPWSMessageW {
data: Vec<u8>,
option_base: u16,
}
use coap_message_utils::option_extension::encode_extensions;
impl CoAPWSMessageW {
pub fn new(token: &[u8]) -> Self {
assert!(token.len() <= 8);
let mut data = Vec::with_capacity(token.len() + 2);
data.push(token.len() as u8);
data.push(0); data.extend_from_slice(&token);
Self { data, option_base: 0 }
}
pub fn serialize(self) -> Vec<u8> {
self.data
}
}
impl coap_message::MinimalWritableMessage for CoAPWSMessageW {
type Code = u8;
type OptionNumber = u16;
fn set_code(&mut self, code: u8) {
self.data[1] = code;
}
fn add_option(&mut self, optnum: u16, value: &[u8]) {
assert!(value.len() <= u16::MAX.into());
let delta = optnum - self.option_base;
self.option_base = optnum;
let len = value.len() as u16;
self.data.extend_from_slice(encode_extensions(delta, len).as_ref());
self.data.extend_from_slice(value);
}
fn set_payload(&mut self, payload: &[u8]) {
if payload.len() > 0 {
self.data.push(0xff);
self.data.extend_from_slice(payload);
}
}
}
use coap_message_utils::inmemory::{EncodedMessageView, EncodedMessage};
#[derive(Debug, Clone)]
pub struct CoAPWSMessageR<B: AsRef<[u8]>>(EncodedMessageView<CoAPWSEncodedMessage<B>>);
#[derive(Clone, Debug)]
pub struct CoAPWSEncodedMessage<B: AsRef<[u8]>>(B);
impl<B: AsRef<[u8]>> EncodedMessage for CoAPWSEncodedMessage<B> {
fn code(&self) -> u8 {
self.0.as_ref()[1]
}
fn options_and_payload(&self) -> &[u8] {
&self.0.as_ref()[(self.0.as_ref()[0] as usize) + 2..]
}
}
impl<B: AsRef<[u8]>> CoAPWSMessageR<B> {
pub fn new(data: B) -> Result<Self, &'static str> {
let len_tkl = *data.as_ref().get(0).ok_or("Zero message")?;
if len_tkl > 8 {
return Err("Invalid first byte");
}
let tkl = len_tkl;
if data.as_ref().len() < 2 + (tkl as usize) {
return Err("Message too short for token");
}
Ok(Self(EncodedMessageView::new(CoAPWSEncodedMessage(data))))
}
pub fn token(&self) -> &[u8] {
let original_slice = self.0.as_ref().0.as_ref();
&original_slice[2..2 + (original_slice[0] as usize)]
}
}
impl<B: AsRef<[u8]>> coap_message::ReadableMessage for CoAPWSMessageR<B> {
type Code = <EncodedMessageView<CoAPWSEncodedMessage<B>> as coap_message::ReadableMessage>::Code;
type MessageOption<'a> = <EncodedMessageView<CoAPWSEncodedMessage<B>> as coap_message::ReadableMessage>::MessageOption<'a> where Self: 'a;
type OptionsIter<'a> = <EncodedMessageView<CoAPWSEncodedMessage<B>> as coap_message::ReadableMessage>::OptionsIter<'a> where Self: 'a;
fn code(&self) -> u8 {
self.0.code()
}
fn payload(&self) -> &[u8] {
self.0.payload()
}
fn options(&self) -> Self::OptionsIter<'_> {
self.0.options()
}
}