Skip to main content

commonware_codec/types/
mod.rs

1//! Codec implementations for common types
2
3use 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
22/// Read keyed items from [Buf] in ascending order.
23pub(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        // Read key
39        let key = K::read_cfg(buf, k_cfg)?;
40
41        // Check if keys are in ascending order relative to the previous key
42        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        // Read value
51        let value = V::read_cfg(buf, v_cfg)?;
52
53        // Add previous item, if exists
54        if let Some((last_key, last_value)) = last.take() {
55            insert(last_key, last_value);
56        }
57        last = Some((key, value));
58    }
59
60    // Add last item, if exists
61    if let Some((last_key, last_value)) = last {
62        insert(last_key, last_value);
63    }
64
65    Ok(())
66}
67
68/// Read items from [Buf] in ascending order.
69pub(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        // Read item
83        let item = K::read_cfg(buf, cfg)?;
84
85        // Check if items are in ascending order
86        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        // Add previous item, if exists
95        if let Some(last) = last.take() {
96            insert(last);
97        }
98        last = Some(item);
99    }
100
101    // Add last item, if exists
102    if let Some(last) = last {
103        insert(last);
104    }
105
106    Ok(())
107}