extern crate alloc;
fn test_read(message: &impl coap_message::ReadableMessage<Code = u8>) {
use coap_message::*;
assert!(message.code() == 0x45);
let expected_options = [
(11, b"short".to_vec()),
(11, b"very-long-option".to_vec()),
(65000, b"".to_vec()),
];
let found_options: alloc::vec::Vec<_> = message
.options()
.map(|o| (o.number(), o.value().to_vec()))
.collect();
assert!(found_options == expected_options);
assert!(message.payload() == b"payload");
}
#[test]
fn test_inmemory() {
let local_body =
alloc::boxed::Box::new(b"\xb5short\r\x03very-long-option\xe0\xfc\xd0\xffpayload");
let message = crate::inmemory::Message::new(0x45, local_body.as_slice());
test_read(&message)
}
#[test]
#[cfg(feature = "downcast")]
fn test_inmemory_downcast() {
let local_body =
alloc::boxed::Box::new(b"\xb5short\r\x03very-long-option\xe0\xfc\xd0\xffpayload");
let message = crate::inmemory::Message::new(0x45, local_body.as_slice());
fn hide_type<'a>(
message: &'a crate::inmemory::Message<'a>,
) -> &'a (impl coap_message::ReadableMessage + 'a) {
message
}
let hidden = hide_type(&message);
let message_again = crate::inmemory::Message::downcast_from(hidden).unwrap();
test_read(message_again)
}
#[test]
fn test_inmemory_write() {
use coap_message::*;
let mut code = 0;
let mut buffer = [0; 100];
let mut message = crate::inmemory_write::Message::new(&mut code, &mut buffer);
message.set_code(0x45);
assert!(
message.options().next().is_none(),
"Nascent message returned options"
);
assert!(
message.payload().is_empty(),
"Nascent message returned payload"
);
message.add_option(11, b"-----").unwrap();
message.add_option(11, b"very-long-option").unwrap();
message.add_option(65000, b"").unwrap();
assert_eq!(
message.options().count(),
3,
"Written options are not read back"
);
message.set_payload(b"payload123").unwrap();
assert_eq!(
message.payload(),
b"payload123",
"Written payloadis not read back"
);
message.truncate(7).unwrap();
assert_eq!(
message.payload(),
b"payload",
"Truncated payloadis not read back"
);
message.mutate_options(|n, v| {
if n == 11 && v.len() == 5 {
v.copy_from_slice(b"short");
}
});
let len = message.finish();
assert!(code == 0x45);
assert!(&buffer[..len] == b"\xb5short\r\x03very-long-option\xe0\xfc\xd0\xffpayload");
}
#[test]
#[cfg(feature = "downcast")]
fn test_inmemory_write_downcast() {
use coap_message::*;
let mut code = 0;
let mut buffer = [0; 100];
let mut message = crate::inmemory_write::Message::new(&mut code, &mut buffer);
fn hide_type_mut<'a, 'b>(
message: &'a mut crate::inmemory_write::Message<'b>,
) -> &'a mut (impl coap_message::MinimalWritableMessage + 'b) {
message
}
let hidden = hide_type_mut(&mut message);
let concrete_again = crate::inmemory_write::Message::downcast_from(hidden).unwrap();
concrete_again.set_code(0x45);
concrete_again.add_option(11, b"-----").unwrap();
concrete_again.add_option(11, b"very-long-option").unwrap();
message.add_option(65000, b"").unwrap();
message.set_payload(b"payload123").unwrap();
message.truncate(7).unwrap();
message.mutate_options(|n, v| {
if n == 11 && v.len() == 5 {
v.copy_from_slice(b"short");
}
});
let len = message.finish();
assert!(code == 0x45);
assert!(&buffer[..len] == b"\xb5short\r\x03very-long-option\xe0\xfc\xd0\xffpayload");
}
#[test]
fn test_inmemory_mutable() {
use coap_message::MutableWritableMessage;
let mut code = 0x45;
let mut buffer = *b"\xb5short\r\x03very-long-option\xe0\xfc\xd0\xffpayload";
let mut message = crate::inmemory_write::Message::new_from_existing(&mut code, &mut buffer);
test_read(&message);
assert!(message.payload_mut_with_len(7).unwrap() == b"payload");
message.payload_mut_with_len(7).unwrap()[6] = b'D';
assert!(&buffer[buffer.len() - 1..] == b"D");
}
#[test]
fn test_inmemory_errors() {
use coap_message::*;
let bodies = [
(b"\xb5sh".as_slice(), 0),
(b"\xbf".as_slice(), 0),
(b"\x0e\xff\xff".as_slice(), 0),
(b"\xe0\xfe\x00\xd0\xff".as_slice(), 1),
];
for (body, discard_options) in bodies {
let message = crate::inmemory::Message::new(0x45, body);
assert!(b"" == message.payload());
let mut optit = message.options();
for _ in 0..discard_options {
assert!(
optit
.next()
.map(|o| o.number() != crate::inmemory::OPTION_INVALID)
== Some(true)
);
}
assert!(optit.next().map(|o| o.number()) == Some(crate::inmemory::OPTION_INVALID));
}
}
#[test]
fn test_encoding() {
use crate::option_extension::encode_extensions;
let example_options = [
(11, &b"short"[..]),
(11, &b"very-long-option"[..]),
(65000, &b""[..]),
];
let expected_encoding = b"\xb5short\r\x03very-long-option\xe0\xfc\xd0";
let mut encoded = alloc::vec::Vec::new();
let mut option = 0u16;
for e in example_options.iter() {
let delta = e.0 - option;
option = e.0;
encoded.extend_from_slice(encode_extensions(delta, e.1.len() as _).as_ref());
encoded.extend_from_slice(e.1);
}
assert_eq!(&expected_encoding.as_ref(), &encoded);
}