Skip to main content

pipa/value/
map.rs

1// SPDX-FileCopyrightText: Copyright 2026 olav@occy.org
2// SPDX-License-Identifier: MPL-2.0
3
4//! A map from bytes to values.
5
6use crate::serde::byte_keys_as_strings;
7use crate::value::Value;
8use crate::value::equivalent::Equivalent;
9use crate::value::keys::Keys;
10use crate::value::meta::Meta;
11use crate::value::print::Print;
12use crate::value::tracer::Tracer;
13use indexmap::IndexMap;
14use indexmap::map::Entry;
15use serde::Deserialize;
16use serde::Serialize;
17
18#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
19pub struct Map {
20    #[serde(default, skip_serializing_if = "Tracer::is_empty")]
21    pub(crate) tracer: Tracer,
22    #[serde(default, skip_serializing_if = "Meta::is_empty")]
23    pub(crate) meta: Meta,
24    #[serde(with = "byte_keys_as_strings")]
25    pub(crate) data: IndexMap<Vec<u8>, Value, ahash::RandomState>,
26}
27
28impl core::fmt::Debug for Map {
29    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30        f.debug_struct("Map")
31            .field("tracer", &self.tracer)
32            .field("meta", &self.meta)
33            .field("data", &DebugMap(&self.data))
34            .finish()
35    }
36}
37
38impl core::fmt::Display for Map {
39    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
40        f.write_str(&String::from_utf8_lossy(&self.clone().print_syntax()))
41    }
42}
43
44struct DebugMap<'a>(&'a IndexMap<Vec<u8>, Value, ahash::RandomState>);
45
46impl core::hash::Hash for Map {
47    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
48        for (k, v) in &self.data {
49            k.hash(state);
50            v.hash(state);
51        }
52    }
53}
54
55impl core::fmt::Debug for DebugMap<'_> {
56    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57        f.debug_map()
58            .entries(self.0.iter().map(|(k, v)| (String::from_utf8_lossy(k), v)))
59            .finish()
60    }
61}
62
63impl<K: Into<Vec<u8>>, V: Into<Value>> From<(K, V)> for Map {
64    fn from(value: (K, V)) -> Self {
65        [value].into_iter().collect()
66    }
67}
68
69impl<K: Into<Vec<u8>>, V: Into<Value>> FromIterator<(K, V)> for Map {
70    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
71        Self {
72            data: iter
73                .into_iter()
74                .map(|(k, v)| (k.into(), v.into()))
75                .collect(),
76            ..Default::default()
77        }
78    }
79}
80
81impl FromIterator<Map> for Map {
82    fn from_iter<T: IntoIterator<Item = Map>>(iter: T) -> Self {
83        Self {
84            data: iter.into_iter().flat_map(Map::into_iter).collect(),
85            ..Default::default()
86        }
87    }
88}
89
90impl FromIterator<(Keys, Value)> for Map {
91    fn from_iter<T: IntoIterator<Item = (Keys, Value)>>(iter: T) -> Self {
92        Self {
93            data: iter.into_iter().map(|(k, v)| (k.join(), v)).collect(),
94            ..Default::default()
95        }
96    }
97}
98
99impl IntoIterator for Map {
100    type Item = (Vec<u8>, Value);
101    type IntoIter = <IndexMap<Vec<u8>, Value> as IntoIterator>::IntoIter;
102
103    fn into_iter(self) -> Self::IntoIter {
104        self.data.into_iter()
105    }
106}
107
108impl Map {
109    pub(crate) fn trace<T: Into<Tracer>>(&mut self, tracer: T) {
110        self.tracer.trace(tracer);
111    }
112
113    pub(crate) fn tracer(&self) -> &Tracer {
114        &self.tracer
115    }
116
117    pub fn with<K: Into<Vec<u8>>, V: Into<Value>>(mut self, key: K, value: V) -> Self {
118        self.fold_key(key.into(), value.into());
119        self
120    }
121
122    pub fn with_fold(mut self, other: Self) -> Self {
123        self.fold(other);
124        self
125    }
126
127    pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> bool {
128        self.data.contains_key(key.as_ref())
129    }
130
131    pub fn contains_value(&self, value: &Value) -> bool {
132        self.data.iter().any(|(_, v)| v.equivalent(value))
133    }
134
135    pub fn iter(&self) -> impl Iterator<Item = (&Vec<u8>, &Value)> {
136        self.data.iter()
137    }
138
139    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&Vec<u8>, &mut Value)> {
140        self.data.iter_mut()
141    }
142
143    pub fn is_empty(&self) -> bool {
144        self.data.is_empty()
145    }
146
147    pub fn clear(mut self) -> Self {
148        self.data = IndexMap::default();
149        self
150    }
151
152    pub fn join(self) -> Vec<u8> {
153        self.data.into_values().flat_map(Value::join).collect()
154    }
155
156    pub fn sort(&mut self) {
157        self.data.sort_keys();
158    }
159
160    pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Option<&Value> {
161        self.data.get(key.as_ref())
162    }
163
164    pub fn get_mut<'a>(&'a mut self, key: &[u8]) -> Option<&'a mut Value> {
165        self.data.get_mut(key)
166    }
167
168    pub fn shift_remove<K: AsRef<[u8]>>(&mut self, key: K) -> Option<Value> {
169        self.data.shift_remove(key.as_ref())
170    }
171
172    pub fn swap_remove<K: AsRef<[u8]>>(&mut self, key: K) -> Option<Value> {
173        self.data.swap_remove(key.as_ref())
174    }
175
176    #[doc(hidden)]
177    pub fn fold(&mut self, other: Self) {
178        for (key, value) in other.data {
179            match self.data.entry(key.clone()) {
180                Entry::Occupied(mut e) => {
181                    e.get_mut().fold(value);
182                }
183                Entry::Vacant(_) => match other.meta.get(b"internal-insert") {
184                    Some(b"prepend") => self.insert_prepend(key, value),
185                    _ => self.insert_append(key, value),
186                },
187            }
188        }
189    }
190
191    #[doc(hidden)]
192    pub fn fold_key<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
193        let key = key.into();
194        let value = value.into();
195
196        match self.data.entry(key.clone()) {
197            Entry::Occupied(mut e) => e.get_mut().fold(value),
198            Entry::Vacant(_) => drop(self.insert(key, value)),
199        }
200    }
201
202    pub fn insert<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
203        let key = key.into();
204        let value = value.into();
205
206        match value.meta().get(b"internal-insert") {
207            Some(b"prepend") => self.insert_prepend(key, value),
208            _ => self.insert_append(key, value),
209        }
210    }
211
212    fn insert_append<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
213        self.data.insert(key.into(), value.into());
214    }
215
216    fn insert_prepend<K: Into<Vec<u8>>, V: Into<Value>>(&mut self, key: K, value: V) {
217        self.data.insert_before(0, key.into(), value.into());
218    }
219}