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