commonware_codec/types/
mod.rs1use crate::{Error, Read};
4use ::bytes::Buf;
5use core::cmp::Ordering;
6
7pub mod btree_map;
8pub mod btree_set;
9pub mod bytes;
10#[cfg(feature = "std")]
11pub mod hash_map;
12#[cfg(feature = "std")]
13pub mod hash_set;
14pub mod lazy;
15#[cfg(feature = "std")]
16pub mod net;
17pub mod primitives;
18pub mod tuple;
19pub mod vec;
20
21pub(crate) fn read_ordered_map<K, V, F>(
23 buf: &mut impl Buf,
24 len: usize,
25 k_cfg: &K::Cfg,
26 v_cfg: &V::Cfg,
27 mut insert: F,
28 map_type: &'static str,
29) -> Result<(), Error>
30where
31 K: Read + Ord,
32 V: Read,
33 F: FnMut(K, V) -> Option<V>,
34{
35 let mut last: Option<(K, V)> = None;
36 for _ in 0..len {
37 let key = K::read_cfg(buf, k_cfg)?;
39
40 if let Some((ref last_key, _)) = last {
42 match key.cmp(last_key) {
43 Ordering::Equal => return Err(Error::Invalid(map_type, "Duplicate key")),
44 Ordering::Less => return Err(Error::Invalid(map_type, "Keys must ascend")),
45 _ => {}
46 }
47 }
48
49 let value = V::read_cfg(buf, v_cfg)?;
51
52 if let Some((last_key, last_value)) = last.take() {
54 insert(last_key, last_value);
55 }
56 last = Some((key, value));
57 }
58
59 if let Some((last_key, last_value)) = last {
61 insert(last_key, last_value);
62 }
63
64 Ok(())
65}
66
67pub(crate) fn read_ordered_set<K, F>(
69 buf: &mut impl Buf,
70 len: usize,
71 cfg: &K::Cfg,
72 mut insert: F,
73 set_type: &'static str,
74) -> Result<(), Error>
75where
76 K: Read + Ord,
77 F: FnMut(K) -> bool,
78{
79 let mut last: Option<K> = None;
80 for _ in 0..len {
81 let item = K::read_cfg(buf, cfg)?;
83
84 if let Some(ref last) = last {
86 match item.cmp(last) {
87 Ordering::Equal => return Err(Error::Invalid(set_type, "Duplicate item")),
88 Ordering::Less => return Err(Error::Invalid(set_type, "Items must ascend")),
89 _ => {}
90 }
91 }
92
93 if let Some(last) = last.take() {
95 insert(last);
96 }
97 last = Some(item);
98 }
99
100 if let Some(last) = last {
102 insert(last);
103 }
104
105 Ok(())
106}
107
108#[cfg(test)]
109pub(crate) mod tests {
110 use crate::{BufsMut, Error, Read, Write};
111 use bytes::{Buf, BufMut, Bytes, BytesMut, buf::UninitSlice};
112
113 #[derive(Debug, PartialEq, Eq)]
118 pub struct Byte(pub u8);
119
120 impl Write for Byte {
121 fn write(&self, buf: &mut impl BufMut) {
122 buf.put_u8(self.0);
123 }
124 }
125
126 impl Read for Byte {
127 type Cfg = ();
128
129 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
130 Ok(Self(<u8 as Read>::read_cfg(buf, &())?))
131 }
132 }
133
134 pub struct TrackingWriteBuf {
140 inner: BytesMut,
141 pub put_slice_calls: usize,
143 pub put_u8_calls: usize,
145 pub push_calls: usize,
147 }
148
149 impl TrackingWriteBuf {
150 pub fn new() -> Self {
151 Self {
152 inner: BytesMut::new(),
153 put_slice_calls: 0,
154 put_u8_calls: 0,
155 push_calls: 0,
156 }
157 }
158
159 pub fn freeze(self) -> Bytes {
160 self.inner.freeze()
161 }
162 }
163
164 unsafe impl BufMut for TrackingWriteBuf {
168 fn remaining_mut(&self) -> usize {
169 self.inner.remaining_mut()
170 }
171
172 fn chunk_mut(&mut self) -> &mut UninitSlice {
173 self.inner.chunk_mut()
174 }
175
176 unsafe fn advance_mut(&mut self, cnt: usize) {
177 unsafe { self.inner.advance_mut(cnt) }
181 }
182
183 fn put_slice(&mut self, src: &[u8]) {
184 self.put_slice_calls += 1;
185 self.inner.put_slice(src);
186 }
187
188 fn put_u8(&mut self, n: u8) {
189 self.put_u8_calls += 1;
190 self.inner.put_u8(n);
191 }
192 }
193
194 impl BufsMut for TrackingWriteBuf {
195 fn push(&mut self, bytes: impl Into<Bytes>) {
196 let bytes = bytes.into();
197 self.push_calls += 1;
198 self.inner.extend_from_slice(&bytes);
199 }
200 }
201
202 pub struct TrackingReadBuf {
208 inner: Bytes,
209 pub copy_to_slice_calls: usize,
211 pub get_u8_calls: usize,
213 }
214
215 impl TrackingReadBuf {
216 pub fn new(bytes: &'static [u8]) -> Self {
217 Self {
218 inner: Bytes::from_static(bytes),
219 copy_to_slice_calls: 0,
220 get_u8_calls: 0,
221 }
222 }
223 }
224
225 impl Buf for TrackingReadBuf {
226 fn remaining(&self) -> usize {
227 self.inner.remaining()
228 }
229
230 fn chunk(&self) -> &[u8] {
231 self.inner.chunk()
232 }
233
234 fn advance(&mut self, cnt: usize) {
235 self.inner.advance(cnt)
236 }
237
238 fn copy_to_slice(&mut self, dst: &mut [u8]) {
239 self.copy_to_slice_calls += 1;
240 self.inner.copy_to_slice(dst);
241 }
242
243 fn get_u8(&mut self) -> u8 {
244 self.get_u8_calls += 1;
245 self.inner.get_u8()
246 }
247 }
248}