coap_lite/
impl_coap_message.rs

1use alloc::vec::Vec;
2
3use coap_message::{
4    Code, MinimalWritableMessage, MutableWritableMessage, OptionNumber,
5    ReadableMessage, SeekWritableMessage, WithSortedOptions,
6};
7
8use crate::{CoapOption, MessageClass, Packet};
9
10impl Code for MessageClass {
11    // Conveniently, it already satisfies the requirements
12}
13
14// pub only in name: We don't expose this whole module, so all users will know
15// is that this is a suitable iterator.
16pub struct MessageOptionAdapter<'a> {
17    head: Option<(u16, alloc::collections::linked_list::Iter<'a, Vec<u8>>)>,
18    // right from Packet::options -- fortunately that doesn't say that it
19    // returns an impl Iterator
20    raw_iter: alloc::collections::btree_map::Iter<
21        'a,
22        u16,
23        alloc::collections::linked_list::LinkedList<Vec<u8>>,
24    >,
25}
26
27// pub only in name: We don't expose this whole module, so all users will know
28// is that this implements coap_message::MessageOption
29pub struct MessageOption<'a> {
30    number: u16,
31    value: &'a [u8],
32}
33
34impl<'a> Iterator for MessageOptionAdapter<'a> {
35    type Item = MessageOption<'a>;
36
37    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
38        loop {
39            if let Some((number, values)) = self.head.as_mut() {
40                if let Some(value) = values.next() {
41                    return Some(MessageOption {
42                        number: *number,
43                        value,
44                    });
45                }
46            }
47            let (number, values) = self.raw_iter.next()?;
48            self.head = Some((*number, values.iter()));
49        }
50    }
51}
52
53impl coap_message::MessageOption for MessageOption<'_> {
54    fn number(&self) -> u16 {
55        self.number
56    }
57    fn value(&self) -> &[u8] {
58        self.value
59    }
60}
61
62impl ReadableMessage for Packet {
63    type Code = MessageClass;
64
65    type MessageOption<'a> = MessageOption<'a>;
66    type OptionsIter<'a> = MessageOptionAdapter<'a>;
67
68    fn code(&self) -> Self::Code {
69        self.header.code
70    }
71    fn payload(&self) -> &[u8] {
72        &self.payload
73    }
74    fn options(&self) -> Self::OptionsIter<'_> {
75        MessageOptionAdapter {
76            raw_iter: self.options.iter(),
77            head: None,
78        }
79    }
80}
81
82impl WithSortedOptions for Packet {}
83
84impl OptionNumber for CoapOption {}
85
86impl MinimalWritableMessage for Packet {
87    type Code = MessageClass;
88    type OptionNumber = CoapOption;
89
90    fn set_code(&mut self, code: Self::Code) {
91        self.header.code = code;
92    }
93
94    fn add_option(&mut self, option: Self::OptionNumber, data: &[u8]) {
95        self.add_option(option, data.into());
96    }
97
98    fn set_payload(&mut self, payload: &[u8]) {
99        self.payload = payload.into();
100    }
101}
102
103impl MutableWritableMessage for Packet {
104    fn available_space(&self) -> usize {
105        usize::MAX
106    }
107    fn payload_mut(&mut self) -> &mut [u8] {
108        &mut self.payload
109    }
110    fn payload_mut_with_len(&mut self, len: usize) -> &mut [u8] {
111        self.payload.resize(len, 0);
112        &mut self.payload
113    }
114    fn truncate(&mut self, length: usize) {
115        self.payload.truncate(length)
116    }
117    fn mutate_options<F>(&mut self, mut callback: F)
118    where
119        F: FnMut(Self::OptionNumber, &mut [u8]),
120    {
121        for (&number, ref mut values) in self.options.iter_mut() {
122            for v in values.iter_mut() {
123                callback(number.into(), v);
124            }
125        }
126    }
127}
128
129impl SeekWritableMessage for Packet {}