|
1 | 1 | use crate::{collections::Vec, error::OutOfMemory}; |
2 | 2 | use core::{fmt, ops::Index}; |
3 | 3 | use cranelift_entity::{EntityRef, SecondaryMap as Inner}; |
4 | | -use serde::ser::SerializeSeq; |
5 | 4 |
|
6 | 5 | /// Like [`cranelift_entity::SecondaryMap`] but all allocation is fallible. |
7 | 6 | pub struct SecondaryMap<K, V> |
@@ -159,30 +158,138 @@ where |
159 | 158 | impl<K, V> serde::ser::Serialize for SecondaryMap<K, V> |
160 | 159 | where |
161 | 160 | K: EntityRef, |
162 | | - V: Clone + serde::ser::Serialize, |
| 161 | + V: Clone + PartialEq + serde::ser::Serialize, |
163 | 162 | { |
164 | 163 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
165 | 164 | where |
166 | 165 | S: serde::Serializer, |
167 | 166 | { |
168 | | - let mut seq = serializer.serialize_seq(Some(self.capacity()))?; |
169 | | - for elem in self.values() { |
170 | | - seq.serialize_element(elem)?; |
| 167 | + use serde::ser::SerializeSeq as _; |
| 168 | + |
| 169 | + // Ignore any trailing default values. |
| 170 | + let mut len = self.inner.as_values_slice().len(); |
| 171 | + while len > 0 && &self[K::new(len - 1)] == self.inner.default_value() { |
| 172 | + len -= 1; |
| 173 | + } |
| 174 | + |
| 175 | + // Plus one for the default value. |
| 176 | + let mut seq = serializer.serialize_seq(Some(len + 1))?; |
| 177 | + |
| 178 | + // Always serialize the default value first. |
| 179 | + seq.serialize_element(self.inner.default_value())?; |
| 180 | + |
| 181 | + for elem in self.values().take(len) { |
| 182 | + let elem = if elem == self.inner.default_value() { |
| 183 | + None |
| 184 | + } else { |
| 185 | + Some(elem) |
| 186 | + }; |
| 187 | + seq.serialize_element(&elem)?; |
171 | 188 | } |
| 189 | + |
172 | 190 | seq.end() |
173 | 191 | } |
174 | 192 | } |
175 | 193 |
|
176 | 194 | impl<'de, K, V> serde::de::Deserialize<'de> for SecondaryMap<K, V> |
177 | 195 | where |
178 | 196 | K: EntityRef, |
179 | | - V: Clone + Default + serde::de::Deserialize<'de>, |
| 197 | + V: Clone + serde::de::Deserialize<'de>, |
180 | 198 | { |
181 | 199 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
182 | 200 | where |
183 | 201 | D: serde::Deserializer<'de>, |
184 | 202 | { |
185 | | - let values: Vec<V> = serde::de::Deserialize::deserialize(deserializer)?; |
186 | | - Ok(Self::from(values)) |
| 203 | + struct Visitor<K, V>(core::marker::PhantomData<fn() -> SecondaryMap<K, V>>) |
| 204 | + where |
| 205 | + K: EntityRef, |
| 206 | + V: Clone; |
| 207 | + |
| 208 | + impl<'de, K, V> serde::de::Visitor<'de> for Visitor<K, V> |
| 209 | + where |
| 210 | + K: EntityRef, |
| 211 | + V: Clone + serde::de::Deserialize<'de>, |
| 212 | + { |
| 213 | + type Value = SecondaryMap<K, V>; |
| 214 | + |
| 215 | + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 216 | + f.write_str("struct SecondaryMap") |
| 217 | + } |
| 218 | + |
| 219 | + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> |
| 220 | + where |
| 221 | + A: serde::de::SeqAccess<'de>, |
| 222 | + { |
| 223 | + // Minus one to account for the default element, which is always |
| 224 | + // the first in the sequence. |
| 225 | + let size_hint = seq.size_hint().and_then(|n| n.checked_sub(1)); |
| 226 | + |
| 227 | + let Some(default) = seq.next_element::<V>()? else { |
| 228 | + return Err(serde::de::Error::custom("Default value required")); |
| 229 | + }; |
| 230 | + |
| 231 | + let mut map = SecondaryMap::<K, V>::with_default(default.clone()); |
| 232 | + |
| 233 | + if let Some(n) = size_hint { |
| 234 | + map.resize(n).map_err(|oom| serde::de::Error::custom(oom))?; |
| 235 | + } |
| 236 | + |
| 237 | + let mut idx = 0; |
| 238 | + while let Some(val) = seq.next_element::<Option<V>>()? { |
| 239 | + let key = K::new(idx); |
| 240 | + let val = match val { |
| 241 | + None => default.clone(), |
| 242 | + Some(val) => val, |
| 243 | + }; |
| 244 | + |
| 245 | + map.insert(key, val) |
| 246 | + .map_err(|oom| serde::de::Error::custom(oom))?; |
| 247 | + |
| 248 | + idx += 1; |
| 249 | + } |
| 250 | + |
| 251 | + Ok(map) |
| 252 | + } |
| 253 | + } |
| 254 | + |
| 255 | + deserializer.deserialize_seq(Visitor(core::marker::PhantomData)) |
| 256 | + } |
| 257 | +} |
| 258 | + |
| 259 | +#[cfg(test)] |
| 260 | +mod tests { |
| 261 | + use super::*; |
| 262 | + use crate::error::Result; |
| 263 | + use alloc::vec; |
| 264 | + use alloc::vec::Vec; |
| 265 | + |
| 266 | + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 267 | + struct K(u32); |
| 268 | + crate::entity_impl!(K); |
| 269 | + |
| 270 | + fn k(i: usize) -> K { |
| 271 | + K::new(i) |
| 272 | + } |
| 273 | + |
| 274 | + #[test] |
| 275 | + fn serialize_deserialize() -> Result<()> { |
| 276 | + let mut map = SecondaryMap::<K, u32>::with_default(99); |
| 277 | + map.insert(k(0), 33)?; |
| 278 | + map.insert(k(1), 44)?; |
| 279 | + map.insert(k(2), 55)?; |
| 280 | + map.insert(k(3), 99)?; |
| 281 | + map.insert(k(4), 99)?; |
| 282 | + |
| 283 | + let bytes = postcard::to_allocvec(&map)?; |
| 284 | + let map2: SecondaryMap<K, u32> = postcard::from_bytes(&bytes)?; |
| 285 | + |
| 286 | + for i in 0..10 { |
| 287 | + assert_eq!(map[k(i)], map2[k(i)]); |
| 288 | + } |
| 289 | + |
| 290 | + // Trailing default entries were omitted from the serialization. |
| 291 | + assert_eq!(map2.keys().collect::<Vec<_>>(), vec![k(0), k(1), k(2)]); |
| 292 | + |
| 293 | + Ok(()) |
187 | 294 | } |
188 | 295 | } |
0 commit comments