coap-message-utils 0.3.9

Utilities for using coap-message traits
Documentation
use coap_message::error::RenderableOnMinimal;
use coap_message::{MessageOption, ReadableMessage};

use coap_message_utils::Error;

#[track_caller]
fn assert_just_code(msg: coap_message_implementations::inmemory_write::Message, code: u8) {
    assert_eq!(msg.code(), code, "Code was not set correctly");
    assert_eq!(
        msg.options().next().map(|o| o.number()),
        None,
        "Unexpected option set in error response"
    );
    assert_eq!(
        msg.payload(),
        b"",
        "Unexpected payload set in error response"
    );
}

#[track_caller]
fn assert_9290_diag(
    msg: coap_message_implementations::inmemory_write::Message,
    code: u8,
    diag: &str,
) {
    assert_eq!(msg.code(), code, "Code was not set correctly");
    assert_eq!(
        msg.options().next().unwrap().number(),
        coap_numbers::option::CONTENT_FORMAT,
    );
    assert_eq!(
        coap_numbers::content_format::to_str(
            msg.options()
                .next()
                .unwrap()
                .value_uint()
                .expect("Content format is numeric")
        )
        .expect("Content format should be known"),
        "application/concise-problem-details+cbor"
    );
    assert_eq!(
        cbor_diag::parse_bytes(msg.payload())
            .expect("Payload should be CBOR")
            .to_diag(),
        diag
    );
}

#[test]
fn error_simple() {
    let mut code = 0;
    let mut tail = [0; 100];
    let mut msg =
        coap_message_implementations::inmemory_write::Message::new(&mut code, tail.as_mut());

    let err = Error::not_found();
    err.render(&mut msg).unwrap();

    assert_just_code(msg, coap_numbers::code::NOT_FOUND);
}

#[test]
fn error_badoption() {
    let mut code = 0;
    let mut tail = [0; 100];
    let mut msg =
        coap_message_implementations::inmemory_write::Message::new(&mut code, tail.as_mut());

    let err = Error::bad_option(42);
    err.render(&mut msg).unwrap();

    if cfg!(feature = "error_unprocessed_coap_option") {
        // We may need to update this as cbor-diag becomes less verbose
        assert_9290_diag(msg, coap_numbers::code::BAD_OPTION, "{-8:42_0}");
    } else {
        assert_just_code(msg, coap_numbers::code::BAD_OPTION);
    }
}

#[test]
fn error_rbep() {
    let mut code = 0;
    let mut tail = [0; 100];
    let mut msg =
        coap_message_implementations::inmemory_write::Message::new(&mut code, tail.as_mut());

    let err = Error::bad_request_with_rbep(1234);
    err.render(&mut msg).unwrap();

    if cfg!(feature = "error_unprocessed_coap_option") {
        // We may need to update this as cbor-diag becomes less verbose
        assert_9290_diag(msg, coap_numbers::code::BAD_REQUEST, "{-25_0:1234_1}");
    } else {
        assert_just_code(msg, coap_numbers::code::BAD_REQUEST);
    }
}

#[test]
#[cfg(feature = "error_max_age")]
fn error_maxage() {
    let mut code = 0;
    let mut tail = [0; 100];
    let mut msg =
        coap_message_implementations::inmemory_write::Message::new(&mut code, tail.as_mut());

    let err = Error::service_unavailable().with_max_age(0);
    err.render(&mut msg).unwrap();

    assert_eq!(
        msg.code(),
        coap_numbers::code::SERVICE_UNAVAILABLE,
        "Code was not set correctly"
    );
    assert_eq!(
        msg.options().next().map(|o| o.number()),
        Some(coap_numbers::option::MAX_AGE),
        "Max-Age option was not set"
    );
}

#[test]
fn error_title() {
    let mut code = 0;
    let mut tail = [0; 100];
    let mut msg =
        coap_message_implementations::inmemory_write::Message::new(&mut code, tail.as_mut());

    let err = Error::internal_server_error().with_title("Flux capacitor failure");
    err.render(&mut msg).unwrap();

    assert_eq!(
        msg.options().map(|o| o.number()).collect::<Vec<u16>>(),
        vec![]
    );

    if cfg!(feature = "error_title") {
        assert_eq!(msg.payload(), b"Flux capacitor failure");
    } else {
        assert_just_code(msg, coap_numbers::code::INTERNAL_SERVER_ERROR);
    }

    // Not tested: Combination with RFC9290 errors; it would not be shown there yet.
}