Skip to main content

cbor_core/
map.rs

1use std::collections::{BTreeMap, HashMap};
2
3use crate::Value;
4
5/// Conversion helper for [`Value::map`].
6///
7/// This type wraps `BTreeMap<Value, Value>` and provides `From`
8/// implementations for common collection types, so that
9/// `Value::map()` can accept them all through a single
10/// `impl Into<Map>` bound.
11///
12/// Supported source types (where `K: Into<Value>`, `V: Into<Value>`):
13///
14/// - `[(K, V); N]` — fixed-size array of pairs
15/// - `&[(K, V)]` — slice of pairs (requires `K: Copy, V: Copy`)
16/// - `Vec<(K, V)>` — vector of pairs
17/// - `Box<[(K, V)]>` — boxed slice of pairs
18/// - `BTreeMap<Value, Value>` — already-sorted map (moved as-is)
19/// - `&BTreeMap<K, V>` — borrowed map (requires `K: Copy, V: Copy`)
20/// - `&HashMap<K, V>` — borrowed hash map (requires `K: Copy, V: Copy`)
21/// - `()` — empty map
22///
23/// Keys and values are converted via their `Into<Value>`
24/// implementations. Keys are automatically sorted in CBOR canonical
25/// order.
26///
27/// ```
28/// # use cbor_core::Value;
29/// // From a fixed-size array of pairs:
30/// let m = Value::map([("x", 1), ("y", 2)]);
31///
32/// // From a Vec of pairs with mixed key types:
33/// let pairs: Vec<(Value, Value)> = vec![
34///     (Value::from(1), Value::from("one")),
35///     (Value::from(2), Value::from("two")),
36/// ];
37/// let m = Value::map(pairs);
38///
39/// // From a BTreeMap:
40/// let mut bt = std::collections::BTreeMap::new();
41/// bt.insert(Value::from("a"), Value::from(1));
42/// let m = Value::map(bt);
43///
44/// // From a &HashMap:
45/// let mut hm = std::collections::HashMap::new();
46/// hm.insert(1, 2);
47/// let m = Value::map(&hm);
48///
49/// // Empty map via ():
50/// let m = Value::map(());
51/// assert_eq!(m.len(), Some(0));
52/// ```
53#[derive(Debug, Default, Clone, PartialEq, Eq)]
54pub struct Map(pub(crate) BTreeMap<Value, Value>);
55
56impl Map {
57    /// Create an empty map.
58    #[must_use]
59    pub const fn new() -> Self {
60        Self(BTreeMap::new())
61    }
62
63    /// Borrow the inner `BTreeMap`.
64    #[must_use]
65    pub const fn get_ref(&self) -> &BTreeMap<Value, Value> {
66        &self.0
67    }
68
69    /// Mutably borrow the inner `BTreeMap`.
70    pub fn get_mut(&mut self) -> &mut BTreeMap<Value, Value> {
71        &mut self.0
72    }
73
74    /// Unwrap into the inner `BTreeMap`.
75    #[must_use]
76    pub fn into_inner(self) -> BTreeMap<Value, Value> {
77        self.0
78    }
79}
80
81impl From<BTreeMap<Value, Value>> for Map {
82    fn from(map: BTreeMap<Value, Value>) -> Self {
83        Map(map)
84    }
85}
86
87impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&BTreeMap<K, V>> for Map {
88    fn from(map: &BTreeMap<K, V>) -> Self {
89        Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
90    }
91}
92
93impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&HashMap<K, V>> for Map {
94    fn from(map: &HashMap<K, V>) -> Self {
95        Map(map.iter().map(|(&k, &v)| (k.into(), v.into())).collect())
96    }
97}
98
99impl<K: Into<Value> + Copy, V: Into<Value> + Copy> From<&[(K, V)]> for Map {
100    fn from(slice: &[(K, V)]) -> Self {
101        Self(slice.iter().map(|&(k, v)| (k.into(), v.into())).collect())
102    }
103}
104
105impl<const N: usize, K: Into<Value>, V: Into<Value>> From<[(K, V); N]> for Map {
106    fn from(array: [(K, V); N]) -> Self {
107        Self(array.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
108    }
109}
110
111impl<K: Into<Value>, V: Into<Value>> From<Vec<(K, V)>> for Map {
112    fn from(vec: Vec<(K, V)>) -> Self {
113        Self(vec.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
114    }
115}
116
117impl<K: Into<Value>, V: Into<Value>> From<Box<[(K, V)]>> for Map {
118    fn from(boxed: Box<[(K, V)]>) -> Self {
119        Self(
120            Vec::from(boxed)
121                .into_iter()
122                .map(|(k, v)| (k.into(), v.into()))
123                .collect(),
124        )
125    }
126}
127
128impl From<()> for Map {
129    fn from(_: ()) -> Self {
130        Self(BTreeMap::new())
131    }
132}