use coap_message::ReadableMessage;
struct MinimalMessage {
code: u8,
content_format: Option<u16>,
etag: Option<Vec<u8>>,
payload: Vec<u8>,
}
enum MessageOption<'a> {
EncodedContentFormat([u8; 2]),
EtagReference(&'a [u8]),
}
impl<'a> coap_message::MessageOption for MessageOption<'a> {
fn number(&self) -> u16 {
match self {
MessageOption::EncodedContentFormat(_) => 12,
MessageOption::EtagReference(_) => 4,
}
}
fn value(&self) -> &[u8] {
match self {
MessageOption::EncodedContentFormat(d) => &d[..],
MessageOption::EtagReference(d) => &d,
}
}
}
struct OptionsIter<'a> {
message: &'a MinimalMessage,
emitted_content_format: bool,
emitted_etag: bool,
}
impl<'a> Iterator for OptionsIter<'a> {
type Item = MessageOption<'a>;
fn next(&mut self) -> Option<MessageOption<'a>> {
if !self.emitted_etag {
self.emitted_etag = true;
if let Some(ref e) = self.message.etag {
return Some(MessageOption::EtagReference(e));
}
}
if !self.emitted_content_format {
self.emitted_content_format = true;
if let Some(f) = self.message.content_format {
return Some(MessageOption::EncodedContentFormat(f.to_be_bytes()));
}
}
return None;
}
}
impl ReadableMessage for MinimalMessage {
type Code = u8;
type MessageOption<'a> = MessageOption<'a>;
type OptionsIter<'a> = OptionsIter<'a>;
fn code(&self) -> u8 {
self.code
}
fn payload(&self) -> &[u8] {
self.payload.as_ref()
}
fn options<'a>(&'a self) -> OptionsIter<'a> {
OptionsIter {
message: self,
emitted_content_format: false,
emitted_etag: false,
}
}
}
fn main() {
use coap_message::MessageOption;
let m = MinimalMessage {
code: 0x45, etag: None,
content_format: Some(0),
payload: b"Hello World".to_vec(),
};
for option in m.options() {
if option.number() == 12 {
assert!(
option.value() == &[0, 0],
"Not the expected content format value"
);
} else {
panic!(
"Option {}: {:?} not expected by construction",
option.number(),
option.value()
);
}
}
println!("Message was read as expected");
}