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