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 tuple;
19pub mod vec;
20
21/// Read keyed items from [Buf] in ascending order.
22pub(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        // Read key
38        let key = K::read_cfg(buf, k_cfg)?;
39
40        // Check if keys are in ascending order relative to the previous key
41        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        // Read value
50        let value = V::read_cfg(buf, v_cfg)?;
51
52        // Add previous item, if exists
53        if let Some((last_key, last_value)) = last.take() {
54            insert(last_key, last_value);
55        }
56        last = Some((key, value));
57    }
58
59    // Add last item, if exists
60    if let Some((last_key, last_value)) = last {
61        insert(last_key, last_value);
62    }
63
64    Ok(())
65}
66
67/// Read items from [Buf] in ascending order.
68pub(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        // Read item
82        let item = K::read_cfg(buf, cfg)?;
83
84        // Check if items are in ascending order
85        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        // Add previous item, if exists
94        if let Some(last) = last.take() {
95            insert(last);
96        }
97        last = Some(item);
98    }
99
100    // Add last item, if exists
101    if let Some(last) = last {
102        insert(last);
103    }
104
105    Ok(())
106}