coap_message_implementations/
heap.rs1extern crate alloc;
21use alloc::{vec, vec::Vec};
22use core::convert::Infallible;
23
24use coap_message::{
25 MinimalWritableMessage, MutableWritableMessage, ReadableMessage, SeekWritableMessage,
26 WithSortedOptions,
27};
28
29#[derive(Debug)]
50pub struct HeapMessage {
51 code: u8,
52 options: alloc::collections::BTreeMap<u16, Vec<Vec<u8>>>,
53 payload: Vec<u8>,
54}
55
56impl HeapMessage {
57 pub fn new() -> Self {
58 Self {
59 code: 0,
60 options: alloc::collections::BTreeMap::new(),
61 payload: vec![],
62 }
63 }
64
65 pub fn change_option(&mut self, optnum: u16, occurrence: usize, value: impl Into<Vec<u8>>) {
69 self.options.get_mut(&optnum).unwrap()[occurrence] = value.into();
70 }
71
72 pub fn remove_option(&mut self, optnum: u16, occurrence: usize) {
76 let vec = self.options.get_mut(&optnum).unwrap();
77 vec.remove(occurrence);
78 if vec.len() == 0 {
79 self.options.remove(&optnum);
80 }
81 }
82}
83
84impl MinimalWritableMessage for HeapMessage {
85 type AddOptionError = Infallible;
86 type SetPayloadError = Infallible;
87 type UnionError = Infallible;
88
89 type Code = u8;
90 type OptionNumber = u16;
91
92 fn set_code(&mut self, code: u8) {
93 self.code = code;
94 }
95
96 fn add_option(&mut self, optnum: u16, data: &[u8]) -> Result<(), Infallible> {
97 self.options
98 .entry(optnum)
99 .or_insert(vec![])
100 .push(data.to_vec());
101 Ok(())
102 }
103
104 fn set_payload(&mut self, payload: &[u8]) -> Result<(), Infallible> {
105 self.payload = payload.to_vec();
106 Ok(())
107 }
108}
109
110impl MutableWritableMessage for HeapMessage {
111 fn available_space(&self) -> usize {
112 core::usize::MAX
113 }
114
115 fn payload_mut_with_len(&mut self, len: usize) -> Result<&mut [u8], Infallible> {
116 self.payload.resize(len, 0);
117 Ok(&mut self.payload)
118 }
119
120 fn truncate(&mut self, len: usize) -> Result<(), Infallible> {
121 self.payload.truncate(len);
122 Ok(())
123 }
124
125 fn mutate_options<F>(&mut self, mut callback: F)
126 where
127 F: FnMut(Self::OptionNumber, &mut [u8]),
128 {
129 for (&number, ref mut values) in self.options.iter_mut() {
130 for v in values.iter_mut() {
131 callback(number.into(), v);
132 }
133 }
134 }
135}
136
137impl SeekWritableMessage for HeapMessage {}
138
139pub struct MessageOption<'a> {
140 number: u16,
141 value: &'a [u8],
142}
143
144impl<'a> coap_message::MessageOption for MessageOption<'a> {
145 fn number(&self) -> u16 {
146 self.number
147 }
148 fn value(&self) -> &[u8] {
149 self.value
150 }
151}
152
153pub struct ReadCursor<'a> {
154 iter: alloc::collections::btree_map::Iter<'a, u16, Vec<Vec<u8>>>,
155 popped: (u16, &'a [Vec<u8>]),
156}
157
158impl<'a> Iterator for ReadCursor<'a> {
159 type Item = MessageOption<'a>;
160 fn next(&mut self) -> Option<MessageOption<'a>> {
161 if self.popped.1.len() == 0 {
162 self.popped = self.iter.next().map(|(k, v)| (*k, v.as_slice()))?;
163
164 debug_assert!(
166 self.popped.1.len() > 0,
167 "HeapMessage had present but empty option"
168 );
169 }
170
171 let (first, rest) = self.popped.1.split_at(1);
172 self.popped.1 = rest;
173 Some(MessageOption {
174 number: self.popped.0,
175 value: first[0].as_slice(),
176 })
177 }
178}
179
180impl WithSortedOptions for HeapMessage {
181 }
183
184impl ReadableMessage for HeapMessage {
185 type Code = u8;
186 type MessageOption<'a> = MessageOption<'a>;
187 type OptionsIter<'a> = ReadCursor<'a>;
188
189 fn code(&self) -> u8 {
190 self.code
191 }
192 fn payload(&self) -> &[u8] {
193 &self.payload
194 }
195 fn options<'m>(&'m self) -> ReadCursor<'m> {
196 ReadCursor {
197 iter: self.options.iter(),
198 popped: (0, &[]),
199 }
200 }
201}