1 //! A YAML mapping and its iterator types. 2 3 use crate::{private, Value}; 4 use indexmap::IndexMap; 5 use serde::{Deserialize, Deserializer, Serialize}; 6 use std::cmp::Ordering; 7 use std::collections::hash_map::DefaultHasher; 8 use std::fmt::{self, Display}; 9 use std::hash::{Hash, Hasher}; 10 use std::mem; 11 12 /// A YAML mapping in which the keys and values are both `serde_yaml::Value`. 13 #[derive(Clone, Default, Eq, PartialEq)] 14 pub struct Mapping { 15 map: IndexMap<Value, Value>, 16 } 17 18 impl Mapping { 19 /// Creates an empty YAML map. 20 #[inline] new() -> Self21 pub fn new() -> Self { 22 Self::default() 23 } 24 25 /// Creates an empty YAML map with the given initial capacity. 26 #[inline] with_capacity(capacity: usize) -> Self27 pub fn with_capacity(capacity: usize) -> Self { 28 Mapping { 29 map: IndexMap::with_capacity(capacity), 30 } 31 } 32 33 /// Reserves capacity for at least `additional` more elements to be inserted 34 /// into the map. The map may reserve more space to avoid frequent 35 /// allocations. 36 /// 37 /// # Panics 38 /// 39 /// Panics if the new allocation size overflows `usize`. 40 #[inline] reserve(&mut self, additional: usize)41 pub fn reserve(&mut self, additional: usize) { 42 self.map.reserve(additional); 43 } 44 45 /// Shrinks the capacity of the map as much as possible. It will drop down 46 /// as much as possible while maintaining the internal rules and possibly 47 /// leaving some space in accordance with the resize policy. 48 #[inline] shrink_to_fit(&mut self)49 pub fn shrink_to_fit(&mut self) { 50 self.map.shrink_to_fit(); 51 } 52 53 /// Inserts a key-value pair into the map. If the key already existed, the 54 /// old value is returned. 55 #[inline] insert(&mut self, k: Value, v: Value) -> Option<Value>56 pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> { 57 self.map.insert(k, v) 58 } 59 60 /// Checks if the map contains the given key. 61 #[inline] contains_key<I: Index>(&self, index: I) -> bool62 pub fn contains_key<I: Index>(&self, index: I) -> bool { 63 index.is_key_into(self) 64 } 65 66 /// Returns the value corresponding to the key in the map. 67 #[inline] get<I: Index>(&self, index: I) -> Option<&Value>68 pub fn get<I: Index>(&self, index: I) -> Option<&Value> { 69 index.index_into(self) 70 } 71 72 /// Returns the mutable reference corresponding to the key in the map. 73 #[inline] get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value>74 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> { 75 index.index_into_mut(self) 76 } 77 78 /// Gets the given key's corresponding entry in the map for insertion and/or 79 /// in-place manipulation. 80 #[inline] entry(&mut self, k: Value) -> Entry81 pub fn entry(&mut self, k: Value) -> Entry { 82 match self.map.entry(k) { 83 indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }), 84 indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }), 85 } 86 } 87 88 /// Removes and returns the value corresponding to the key from the map. 89 /// 90 /// This is equivalent to [`.swap_remove(index)`][Self::swap_remove], 91 /// replacing this entry's position with the last element. If you need to 92 /// preserve the relative order of the keys in the map, use 93 /// [`.shift_remove(key)`][Self::shift_remove] instead. 94 #[inline] remove<I: Index>(&mut self, index: I) -> Option<Value>95 pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> { 96 self.swap_remove(index) 97 } 98 99 /// Remove and return the key-value pair. 100 /// 101 /// This is equivalent to [`.swap_remove_entry(index)`][Self::swap_remove_entry], 102 /// replacing this entry's position with the last element. If you need to 103 /// preserve the relative order of the keys in the map, use 104 /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead. 105 #[inline] remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>106 pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> { 107 self.swap_remove_entry(index) 108 } 109 110 /// Removes and returns the value corresponding to the key from the map. 111 /// 112 /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the 113 /// last element of the map and popping it off. This perturbs the position 114 /// of what used to be the last element! 115 #[inline] swap_remove<I: Index>(&mut self, index: I) -> Option<Value>116 pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> { 117 index.swap_remove_from(self) 118 } 119 120 /// Remove and return the key-value pair. 121 /// 122 /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the 123 /// last element of the map and popping it off. This perturbs the position 124 /// of what used to be the last element! 125 #[inline] swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>126 pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> { 127 index.swap_remove_entry_from(self) 128 } 129 130 /// Removes and returns the value corresponding to the key from the map. 131 /// 132 /// Like [`Vec::remove`], the entry is removed by shifting all of the 133 /// elements that follow it, preserving their relative order. This perturbs 134 /// the index of all of those elements! 135 #[inline] shift_remove<I: Index>(&mut self, index: I) -> Option<Value>136 pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> { 137 index.shift_remove_from(self) 138 } 139 140 /// Remove and return the key-value pair. 141 /// 142 /// Like [`Vec::remove`], the entry is removed by shifting all of the 143 /// elements that follow it, preserving their relative order. This perturbs 144 /// the index of all of those elements! 145 #[inline] shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>146 pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> { 147 index.shift_remove_entry_from(self) 148 } 149 150 /// Scan through each key-value pair in the map and keep those where the 151 /// closure `keep` returns true. 152 #[inline] retain<F>(&mut self, keep: F) where F: FnMut(&Value, &mut Value) -> bool,153 pub fn retain<F>(&mut self, keep: F) 154 where 155 F: FnMut(&Value, &mut Value) -> bool, 156 { 157 self.map.retain(keep); 158 } 159 160 /// Returns the maximum number of key-value pairs the map can hold without 161 /// reallocating. 162 #[inline] capacity(&self) -> usize163 pub fn capacity(&self) -> usize { 164 self.map.capacity() 165 } 166 167 /// Returns the number of key-value pairs in the map. 168 #[inline] len(&self) -> usize169 pub fn len(&self) -> usize { 170 self.map.len() 171 } 172 173 /// Returns whether the map is currently empty. 174 #[inline] is_empty(&self) -> bool175 pub fn is_empty(&self) -> bool { 176 self.map.is_empty() 177 } 178 179 /// Clears the map of all key-value pairs. 180 #[inline] clear(&mut self)181 pub fn clear(&mut self) { 182 self.map.clear(); 183 } 184 185 /// Returns a double-ended iterator visiting all key-value pairs in order of 186 /// insertion. Iterator element type is `(&'a Value, &'a Value)`. 187 #[inline] iter(&self) -> Iter188 pub fn iter(&self) -> Iter { 189 Iter { 190 iter: self.map.iter(), 191 } 192 } 193 194 /// Returns a double-ended iterator visiting all key-value pairs in order of 195 /// insertion. Iterator element type is `(&'a Value, &'a mut ValuE)`. 196 #[inline] iter_mut(&mut self) -> IterMut197 pub fn iter_mut(&mut self) -> IterMut { 198 IterMut { 199 iter: self.map.iter_mut(), 200 } 201 } 202 203 /// Return an iterator over the keys of the map. keys(&self) -> Keys204 pub fn keys(&self) -> Keys { 205 Keys { 206 iter: self.map.keys(), 207 } 208 } 209 210 /// Return an owning iterator over the keys of the map. into_keys(self) -> IntoKeys211 pub fn into_keys(self) -> IntoKeys { 212 IntoKeys { 213 iter: self.map.into_keys(), 214 } 215 } 216 217 /// Return an iterator over the values of the map. values(&self) -> Values218 pub fn values(&self) -> Values { 219 Values { 220 iter: self.map.values(), 221 } 222 } 223 224 /// Return an iterator over mutable references to the values of the map. values_mut(&mut self) -> ValuesMut225 pub fn values_mut(&mut self) -> ValuesMut { 226 ValuesMut { 227 iter: self.map.values_mut(), 228 } 229 } 230 231 /// Return an owning iterator over the values of the map. into_values(self) -> IntoValues232 pub fn into_values(self) -> IntoValues { 233 IntoValues { 234 iter: self.map.into_values(), 235 } 236 } 237 } 238 239 /// A type that can be used to index into a `serde_yaml::Mapping`. See the 240 /// methods `get`, `get_mut`, `contains_key`, and `remove` of `Value`. 241 /// 242 /// This trait is sealed and cannot be implemented for types outside of 243 /// `serde_yaml`. 244 pub trait Index: private::Sealed { 245 #[doc(hidden)] is_key_into(&self, v: &Mapping) -> bool246 fn is_key_into(&self, v: &Mapping) -> bool; 247 248 #[doc(hidden)] index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>249 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>; 250 251 #[doc(hidden)] index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>252 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>; 253 254 #[doc(hidden)] swap_remove_from(&self, v: &mut Mapping) -> Option<Value>255 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>; 256 257 #[doc(hidden)] swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>258 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>; 259 260 #[doc(hidden)] shift_remove_from(&self, v: &mut Mapping) -> Option<Value>261 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>; 262 263 #[doc(hidden)] shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>264 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>; 265 } 266 267 struct HashLikeValue<'a>(&'a str); 268 269 impl<'a> indexmap::Equivalent<Value> for HashLikeValue<'a> { equivalent(&self, key: &Value) -> bool270 fn equivalent(&self, key: &Value) -> bool { 271 match key { 272 Value::String(string) => self.0 == string, 273 _ => false, 274 } 275 } 276 } 277 278 // NOTE: This impl must be consistent with Value's Hash impl. 279 impl<'a> Hash for HashLikeValue<'a> { hash<H: Hasher>(&self, state: &mut H)280 fn hash<H: Hasher>(&self, state: &mut H) { 281 const STRING: Value = Value::String(String::new()); 282 mem::discriminant(&STRING).hash(state); 283 self.0.hash(state); 284 } 285 } 286 287 impl Index for Value { is_key_into(&self, v: &Mapping) -> bool288 fn is_key_into(&self, v: &Mapping) -> bool { 289 v.map.contains_key(self) 290 } index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>291 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> { 292 v.map.get(self) 293 } index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>294 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> { 295 v.map.get_mut(self) 296 } swap_remove_from(&self, v: &mut Mapping) -> Option<Value>297 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> { 298 v.map.swap_remove(self) 299 } swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>300 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 301 v.map.swap_remove_entry(self) 302 } shift_remove_from(&self, v: &mut Mapping) -> Option<Value>303 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> { 304 v.map.shift_remove(self) 305 } shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>306 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 307 v.map.shift_remove_entry(self) 308 } 309 } 310 311 impl Index for str { is_key_into(&self, v: &Mapping) -> bool312 fn is_key_into(&self, v: &Mapping) -> bool { 313 v.map.contains_key(&HashLikeValue(self)) 314 } index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>315 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> { 316 v.map.get(&HashLikeValue(self)) 317 } index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>318 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> { 319 v.map.get_mut(&HashLikeValue(self)) 320 } swap_remove_from(&self, v: &mut Mapping) -> Option<Value>321 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> { 322 v.map.swap_remove(&HashLikeValue(self)) 323 } swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>324 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 325 v.map.swap_remove_entry(&HashLikeValue(self)) 326 } shift_remove_from(&self, v: &mut Mapping) -> Option<Value>327 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> { 328 v.map.shift_remove(&HashLikeValue(self)) 329 } shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>330 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 331 v.map.shift_remove_entry(&HashLikeValue(self)) 332 } 333 } 334 335 impl Index for String { is_key_into(&self, v: &Mapping) -> bool336 fn is_key_into(&self, v: &Mapping) -> bool { 337 self.as_str().is_key_into(v) 338 } index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>339 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> { 340 self.as_str().index_into(v) 341 } index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>342 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> { 343 self.as_str().index_into_mut(v) 344 } swap_remove_from(&self, v: &mut Mapping) -> Option<Value>345 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> { 346 self.as_str().swap_remove_from(v) 347 } swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>348 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 349 self.as_str().swap_remove_entry_from(v) 350 } shift_remove_from(&self, v: &mut Mapping) -> Option<Value>351 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> { 352 self.as_str().shift_remove_from(v) 353 } shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>354 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 355 self.as_str().shift_remove_entry_from(v) 356 } 357 } 358 359 impl<T> Index for &T 360 where 361 T: ?Sized + Index, 362 { is_key_into(&self, v: &Mapping) -> bool363 fn is_key_into(&self, v: &Mapping) -> bool { 364 (**self).is_key_into(v) 365 } index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>366 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> { 367 (**self).index_into(v) 368 } index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>369 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> { 370 (**self).index_into_mut(v) 371 } swap_remove_from(&self, v: &mut Mapping) -> Option<Value>372 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> { 373 (**self).swap_remove_from(v) 374 } swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>375 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 376 (**self).swap_remove_entry_from(v) 377 } shift_remove_from(&self, v: &mut Mapping) -> Option<Value>378 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> { 379 (**self).shift_remove_from(v) 380 } shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>381 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> { 382 (**self).shift_remove_entry_from(v) 383 } 384 } 385 386 #[allow(clippy::derived_hash_with_manual_eq)] 387 impl Hash for Mapping { hash<H: Hasher>(&self, state: &mut H)388 fn hash<H: Hasher>(&self, state: &mut H) { 389 // Hash the kv pairs in a way that is not sensitive to their order. 390 let mut xor = 0; 391 for (k, v) in self { 392 let mut hasher = DefaultHasher::new(); 393 k.hash(&mut hasher); 394 v.hash(&mut hasher); 395 xor ^= hasher.finish(); 396 } 397 xor.hash(state); 398 } 399 } 400 401 impl PartialOrd for Mapping { partial_cmp(&self, other: &Self) -> Option<Ordering>402 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 403 let mut self_entries = Vec::from_iter(self); 404 let mut other_entries = Vec::from_iter(other); 405 406 // Sort in an arbitrary order that is consistent with Value's PartialOrd 407 // impl. 408 fn total_cmp(a: &Value, b: &Value) -> Ordering { 409 match (a, b) { 410 (Value::Null, Value::Null) => Ordering::Equal, 411 (Value::Null, _) => Ordering::Less, 412 (_, Value::Null) => Ordering::Greater, 413 414 (Value::Bool(a), Value::Bool(b)) => a.cmp(b), 415 (Value::Bool(_), _) => Ordering::Less, 416 (_, Value::Bool(_)) => Ordering::Greater, 417 418 (Value::Number(a), Value::Number(b)) => a.total_cmp(b), 419 (Value::Number(_), _) => Ordering::Less, 420 (_, Value::Number(_)) => Ordering::Greater, 421 422 (Value::String(a), Value::String(b)) => a.cmp(b), 423 (Value::String(_), _) => Ordering::Less, 424 (_, Value::String(_)) => Ordering::Greater, 425 426 (Value::Sequence(a), Value::Sequence(b)) => iter_cmp_by(a, b, total_cmp), 427 (Value::Sequence(_), _) => Ordering::Less, 428 (_, Value::Sequence(_)) => Ordering::Greater, 429 430 (Value::Mapping(a), Value::Mapping(b)) => { 431 iter_cmp_by(a, b, |(ak, av), (bk, bv)| { 432 total_cmp(ak, bk).then_with(|| total_cmp(av, bv)) 433 }) 434 } 435 (Value::Mapping(_), _) => Ordering::Less, 436 (_, Value::Mapping(_)) => Ordering::Greater, 437 438 (Value::Tagged(a), Value::Tagged(b)) => a 439 .tag 440 .cmp(&b.tag) 441 .then_with(|| total_cmp(&a.value, &b.value)), 442 } 443 } 444 445 fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering 446 where 447 I: IntoIterator, 448 F: FnMut(I::Item, I::Item) -> Ordering, 449 { 450 let mut this = this.into_iter(); 451 let mut other = other.into_iter(); 452 453 loop { 454 let x = match this.next() { 455 None => { 456 if other.next().is_none() { 457 return Ordering::Equal; 458 } else { 459 return Ordering::Less; 460 } 461 } 462 Some(val) => val, 463 }; 464 465 let y = match other.next() { 466 None => return Ordering::Greater, 467 Some(val) => val, 468 }; 469 470 match cmp(x, y) { 471 Ordering::Equal => {} 472 non_eq => return non_eq, 473 } 474 } 475 } 476 477 // While sorting by map key, we get to assume that no two keys are 478 // equal, otherwise they wouldn't both be in the map. This is not a safe 479 // assumption outside of this situation. 480 let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b); 481 self_entries.sort_by(total_cmp); 482 other_entries.sort_by(total_cmp); 483 self_entries.partial_cmp(&other_entries) 484 } 485 } 486 487 impl<I> std::ops::Index<I> for Mapping 488 where 489 I: Index, 490 { 491 type Output = Value; 492 493 #[inline] 494 #[track_caller] index(&self, index: I) -> &Value495 fn index(&self, index: I) -> &Value { 496 index.index_into(self).unwrap() 497 } 498 } 499 500 impl<I> std::ops::IndexMut<I> for Mapping 501 where 502 I: Index, 503 { 504 #[inline] 505 #[track_caller] index_mut(&mut self, index: I) -> &mut Value506 fn index_mut(&mut self, index: I) -> &mut Value { 507 index.index_into_mut(self).unwrap() 508 } 509 } 510 511 impl Extend<(Value, Value)> for Mapping { 512 #[inline] extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I)513 fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) { 514 self.map.extend(iter); 515 } 516 } 517 518 impl FromIterator<(Value, Value)> for Mapping { 519 #[inline] from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self520 fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self { 521 Mapping { 522 map: IndexMap::from_iter(iter), 523 } 524 } 525 } 526 527 macro_rules! delegate_iterator { 528 (($name:ident $($generics:tt)*) => $item:ty) => { 529 impl $($generics)* Iterator for $name $($generics)* { 530 type Item = $item; 531 #[inline] 532 fn next(&mut self) -> Option<Self::Item> { 533 self.iter.next() 534 } 535 #[inline] 536 fn size_hint(&self) -> (usize, Option<usize>) { 537 self.iter.size_hint() 538 } 539 } 540 541 impl $($generics)* ExactSizeIterator for $name $($generics)* { 542 #[inline] 543 fn len(&self) -> usize { 544 self.iter.len() 545 } 546 } 547 } 548 } 549 550 /// Iterator over `&serde_yaml::Mapping`. 551 pub struct Iter<'a> { 552 iter: indexmap::map::Iter<'a, Value, Value>, 553 } 554 555 delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value)); 556 557 impl<'a> IntoIterator for &'a Mapping { 558 type Item = (&'a Value, &'a Value); 559 type IntoIter = Iter<'a>; 560 #[inline] into_iter(self) -> Self::IntoIter561 fn into_iter(self) -> Self::IntoIter { 562 Iter { 563 iter: self.map.iter(), 564 } 565 } 566 } 567 568 /// Iterator over `&mut serde_yaml::Mapping`. 569 pub struct IterMut<'a> { 570 iter: indexmap::map::IterMut<'a, Value, Value>, 571 } 572 573 delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value)); 574 575 impl<'a> IntoIterator for &'a mut Mapping { 576 type Item = (&'a Value, &'a mut Value); 577 type IntoIter = IterMut<'a>; 578 #[inline] into_iter(self) -> Self::IntoIter579 fn into_iter(self) -> Self::IntoIter { 580 IterMut { 581 iter: self.map.iter_mut(), 582 } 583 } 584 } 585 586 /// Iterator over `serde_yaml::Mapping` by value. 587 pub struct IntoIter { 588 iter: indexmap::map::IntoIter<Value, Value>, 589 } 590 591 delegate_iterator!((IntoIter) => (Value, Value)); 592 593 impl IntoIterator for Mapping { 594 type Item = (Value, Value); 595 type IntoIter = IntoIter; 596 #[inline] into_iter(self) -> Self::IntoIter597 fn into_iter(self) -> Self::IntoIter { 598 IntoIter { 599 iter: self.map.into_iter(), 600 } 601 } 602 } 603 604 /// Iterator of the keys of a `&serde_yaml::Mapping`. 605 pub struct Keys<'a> { 606 iter: indexmap::map::Keys<'a, Value, Value>, 607 } 608 609 delegate_iterator!((Keys<'a>) => &'a Value); 610 611 /// Iterator of the keys of a `serde_yaml::Mapping`. 612 pub struct IntoKeys { 613 iter: indexmap::map::IntoKeys<Value, Value>, 614 } 615 616 delegate_iterator!((IntoKeys) => Value); 617 618 /// Iterator of the values of a `&serde_yaml::Mapping`. 619 pub struct Values<'a> { 620 iter: indexmap::map::Values<'a, Value, Value>, 621 } 622 623 delegate_iterator!((Values<'a>) => &'a Value); 624 625 /// Iterator of the values of a `&mut serde_yaml::Mapping`. 626 pub struct ValuesMut<'a> { 627 iter: indexmap::map::ValuesMut<'a, Value, Value>, 628 } 629 630 delegate_iterator!((ValuesMut<'a>) => &'a mut Value); 631 632 /// Iterator of the values of a `serde_yaml::Mapping`. 633 pub struct IntoValues { 634 iter: indexmap::map::IntoValues<Value, Value>, 635 } 636 637 delegate_iterator!((IntoValues) => Value); 638 639 /// Entry for an existing key-value pair or a vacant location to insert one. 640 pub enum Entry<'a> { 641 /// Existing slot with equivalent key. 642 Occupied(OccupiedEntry<'a>), 643 /// Vacant slot (no equivalent key in the map). 644 Vacant(VacantEntry<'a>), 645 } 646 647 /// A view into an occupied entry in a [`Mapping`]. It is part of the [`Entry`] 648 /// enum. 649 pub struct OccupiedEntry<'a> { 650 occupied: indexmap::map::OccupiedEntry<'a, Value, Value>, 651 } 652 653 /// A view into a vacant entry in a [`Mapping`]. It is part of the [`Entry`] 654 /// enum. 655 pub struct VacantEntry<'a> { 656 vacant: indexmap::map::VacantEntry<'a, Value, Value>, 657 } 658 659 impl<'a> Entry<'a> { 660 /// Returns a reference to this entry's key. key(&self) -> &Value661 pub fn key(&self) -> &Value { 662 match self { 663 Entry::Vacant(e) => e.key(), 664 Entry::Occupied(e) => e.key(), 665 } 666 } 667 668 /// Ensures a value is in the entry by inserting the default if empty, and 669 /// returns a mutable reference to the value in the entry. or_insert(self, default: Value) -> &'a mut Value670 pub fn or_insert(self, default: Value) -> &'a mut Value { 671 match self { 672 Entry::Vacant(entry) => entry.insert(default), 673 Entry::Occupied(entry) => entry.into_mut(), 674 } 675 } 676 677 /// Ensures a value is in the entry by inserting the result of the default 678 /// function if empty, and returns a mutable reference to the value in the 679 /// entry. or_insert_with<F>(self, default: F) -> &'a mut Value where F: FnOnce() -> Value,680 pub fn or_insert_with<F>(self, default: F) -> &'a mut Value 681 where 682 F: FnOnce() -> Value, 683 { 684 match self { 685 Entry::Vacant(entry) => entry.insert(default()), 686 Entry::Occupied(entry) => entry.into_mut(), 687 } 688 } 689 690 /// Provides in-place mutable access to an occupied entry before any 691 /// potential inserts into the map. and_modify<F>(self, f: F) -> Self where F: FnOnce(&mut Value),692 pub fn and_modify<F>(self, f: F) -> Self 693 where 694 F: FnOnce(&mut Value), 695 { 696 match self { 697 Entry::Occupied(mut entry) => { 698 f(entry.get_mut()); 699 Entry::Occupied(entry) 700 } 701 Entry::Vacant(entry) => Entry::Vacant(entry), 702 } 703 } 704 } 705 706 impl<'a> OccupiedEntry<'a> { 707 /// Gets a reference to the key in the entry. 708 #[inline] key(&self) -> &Value709 pub fn key(&self) -> &Value { 710 self.occupied.key() 711 } 712 713 /// Gets a reference to the value in the entry. 714 #[inline] get(&self) -> &Value715 pub fn get(&self) -> &Value { 716 self.occupied.get() 717 } 718 719 /// Gets a mutable reference to the value in the entry. 720 #[inline] get_mut(&mut self) -> &mut Value721 pub fn get_mut(&mut self) -> &mut Value { 722 self.occupied.get_mut() 723 } 724 725 /// Converts the entry into a mutable reference to its value. 726 #[inline] into_mut(self) -> &'a mut Value727 pub fn into_mut(self) -> &'a mut Value { 728 self.occupied.into_mut() 729 } 730 731 /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns 732 /// the entry's old value. 733 #[inline] insert(&mut self, value: Value) -> Value734 pub fn insert(&mut self, value: Value) -> Value { 735 self.occupied.insert(value) 736 } 737 738 /// Takes the value of the entry out of the map, and returns it. 739 #[inline] remove(self) -> Value740 pub fn remove(self) -> Value { 741 self.occupied.swap_remove() 742 } 743 744 /// Remove and return the key, value pair stored in the map for this entry. 745 #[inline] remove_entry(self) -> (Value, Value)746 pub fn remove_entry(self) -> (Value, Value) { 747 self.occupied.swap_remove_entry() 748 } 749 } 750 751 impl<'a> VacantEntry<'a> { 752 /// Gets a reference to the key that would be used when inserting a value 753 /// through the VacantEntry. 754 #[inline] key(&self) -> &Value755 pub fn key(&self) -> &Value { 756 self.vacant.key() 757 } 758 759 /// Takes ownership of the key, leaving the entry vacant. 760 #[inline] into_key(self) -> Value761 pub fn into_key(self) -> Value { 762 self.vacant.into_key() 763 } 764 765 /// Sets the value of the entry with the VacantEntry's key, and returns a 766 /// mutable reference to it. 767 #[inline] insert(self, value: Value) -> &'a mut Value768 pub fn insert(self, value: Value) -> &'a mut Value { 769 self.vacant.insert(value) 770 } 771 } 772 773 impl Serialize for Mapping { 774 #[inline] serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>775 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 776 use serde::ser::SerializeMap; 777 let mut map_serializer = serializer.serialize_map(Some(self.len()))?; 778 for (k, v) in self { 779 map_serializer.serialize_entry(k, v)?; 780 } 781 map_serializer.end() 782 } 783 } 784 785 impl<'de> Deserialize<'de> for Mapping { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,786 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 787 where 788 D: Deserializer<'de>, 789 { 790 struct Visitor; 791 792 impl<'de> serde::de::Visitor<'de> for Visitor { 793 type Value = Mapping; 794 795 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 796 formatter.write_str("a YAML mapping") 797 } 798 799 #[inline] 800 fn visit_unit<E>(self) -> Result<Self::Value, E> 801 where 802 E: serde::de::Error, 803 { 804 Ok(Mapping::new()) 805 } 806 807 #[inline] 808 fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error> 809 where 810 A: serde::de::MapAccess<'de>, 811 { 812 let mut mapping = Mapping::new(); 813 814 while let Some(key) = data.next_key()? { 815 match mapping.entry(key) { 816 Entry::Occupied(entry) => { 817 return Err(serde::de::Error::custom(DuplicateKeyError { entry })); 818 } 819 Entry::Vacant(entry) => { 820 let value = data.next_value()?; 821 entry.insert(value); 822 } 823 } 824 } 825 826 Ok(mapping) 827 } 828 } 829 830 deserializer.deserialize_map(Visitor) 831 } 832 } 833 834 struct DuplicateKeyError<'a> { 835 entry: OccupiedEntry<'a>, 836 } 837 838 impl<'a> Display for DuplicateKeyError<'a> { fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result839 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 840 formatter.write_str("duplicate entry ")?; 841 match self.entry.key() { 842 Value::Null => formatter.write_str("with null key"), 843 Value::Bool(boolean) => write!(formatter, "with key `{}`", boolean), 844 Value::Number(number) => write!(formatter, "with key {}", number), 845 Value::String(string) => write!(formatter, "with key {:?}", string), 846 Value::Sequence(_) | Value::Mapping(_) | Value::Tagged(_) => { 847 formatter.write_str("in YAML map") 848 } 849 } 850 } 851 } 852