1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
extern crate coap;

use coap::Server;
use tokio::runtime::Runtime;

use log::info;

fn main() {
    let addr = "localhost:5683";

    let log = coap_message_demos::log::Log::start_once();

    Runtime::new().unwrap().block_on(async move {
        let server = Server::new_udp(addr).unwrap();
        println!("Server up on {}", addr);
        info!("Server up on {}", addr);

        use coap_handler::Handler;

        // Unlike in coap 0.11, the run closure is now Fn, so we can't have an exclusive reference
        // to a handler but need to fan out. To avoid the need for a mutex, we just use a handler
        // factory.
        //
        // Note that this may have "funny" effects w/rt the CBOR editable items, which are shared
        // only across handlers spawned from a single full_application_tree call.
        let handler = || coap_message_demos::full_application_tree(Some(log));

        server
            .run(
                move |mut request: Box<coap_lite::CoapRequest<std::net::SocketAddr>>| {
                    let mut handler = handler();

                    // We can just unwrap because the tokio based surver unwinds crashing handlers.
                    // We could still choose to rather render the errors, because a) it'd provide
                    // concrete information to the client and b) it sends a response instead of
                    // leaving the client hanging -- see the coap-lite example for how that is
                    // done.

                    let extracted = handler.extract_request_data(&request.message).unwrap();

                    if let Some(r) = request.response.as_mut() {
                        handler.build_response(&mut r.message, extracted).unwrap();
                    }

                    async { request }
                },
            )
            .await
            .unwrap();
    });
}