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
52
53
54
55
//! This module implements [coap_message::ReadableMessage] for, and a wrapper that provides
//! [coap_message::WritableMessage] around RIOT's coap_pkt_t.

mod impl_0_2;
mod impl_0_3;

use crate::gcoap::{PacketBuffer, PacketBufferOptIter};

pub struct MessageOption<'a> {
    number: u16,
    value: &'a [u8],
}

pub struct OptionsIterator<'a>(PacketBufferOptIter<'a>);
impl<'a> Iterator for OptionsIterator<'a> {
    type Item = MessageOption<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        let (opt_num, slice) = self.0.next()?;
        Some(MessageOption {
            number: opt_num,
            value: slice,
        })
    }
}

pub struct ResponseMessage<'a> {
    /// Note that this is a slightly weird version of PacketBuffer, where opt_finish is never
    /// called, and .payload() perpetually reports the payload marker as part of the payload.
    message: &'a mut PacketBuffer,
    payload_written: Option<usize>,
}

impl<'a> ResponseMessage<'a> {
    pub fn new(buf: &'a mut PacketBuffer) -> Self {
        // Can't really err; FIXME ensure that such a check won't affect ROM too much
        buf.resp_init(5 << 5).unwrap();

        ResponseMessage {
            message: buf,
            payload_written: None,
        }
    }

    pub(crate) fn rewind(&mut self) {
        self.message.resp_init(5 << 5).unwrap();
    }

    pub fn finish(&self) -> isize {
        self.message.get_length(match self.payload_written {
            None => 0,
            Some(x) => x + 1,
        }) as isize
    }
}