creator_plist/dictionary.rs
1//! A map of String to plist::Value.
2//!
3//! The map is currently backed by an [`IndexMap`]. This may be changed in a future minor release.
4//!
5//! [`IndexMap`]: https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html
6
7//use serde::{de, ser};
8use indexmap::{map, IndexMap};
9use std::{
10 fmt::{self, Debug},
11 iter::FromIterator,
12 ops,
13};
14
15use crate::Value;
16
17/// Represents a plist dictionary type.
18pub struct Dictionary {
19 map: IndexMap<String, Value>,
20}
21
22impl Dictionary {
23 /// Makes a new empty `Dictionary`.
24 #[inline]
25 pub fn new() -> Self {
26 Dictionary {
27 map: IndexMap::new(),
28 }
29 }
30
31 /// Clears the dictionary, removing all values.
32 #[inline]
33 pub fn clear(&mut self) {
34 self.map.clear()
35 }
36
37 /// Returns a reference to the value corresponding to the key.
38 #[inline]
39 pub fn get(&self, key: &str) -> Option<&Value> {
40 self.map.get(key)
41 }
42
43 /// Returns true if the dictionary contains a value for the specified key.
44 #[inline]
45 pub fn contains_key(&self, key: &str) -> bool {
46 self.map.contains_key(key)
47 }
48
49 /// Returns a mutable reference to the value corresponding to the key.
50 #[inline]
51 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
52 self.map.get_mut(key)
53 }
54
55 /// Inserts a key-value pair into the dictionary.
56 ///
57 /// If the dictionary did not have this key present, `None` is returned.
58 ///
59 /// If the dictionary did have this key present, the value is updated, and the old value is
60 /// returned.
61 #[inline]
62 pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
63 self.map.insert(k, v)
64 }
65
66 /// Removes a key from the dictionary, returning the value at the key if the key was previously
67 /// in the dictionary.
68 #[inline]
69 pub fn remove(&mut self, key: &str) -> Option<Value> {
70 self.map.remove(key)
71 }
72
73 /// Gets the given key's corresponding entry in the dictionary for in-place manipulation.
74 // Entry functionality is unstable until I can figure out how to use either Cow<str> or
75 // T: AsRef<str> + Into<String>
76 #[cfg(any(
77 test,
78 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
79 ))]
80 pub fn entry<S>(&mut self, key: S) -> Entry
81 where
82 S: Into<String>,
83 {
84 match self.map.entry(key.into()) {
85 map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
86 map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
87 }
88 }
89
90 /// Returns the number of elements in the dictionary.
91 #[inline]
92 pub fn len(&self) -> usize {
93 self.map.len()
94 }
95
96 /// Returns true if the dictionary contains no elements.
97 #[inline]
98 pub fn is_empty(&self) -> bool {
99 self.map.is_empty()
100 }
101
102 /// Gets an iterator over the entries of the dictionary.
103 #[inline]
104 pub fn iter(&self) -> Iter {
105 Iter {
106 iter: self.map.iter(),
107 }
108 }
109
110 /// Gets a mutable iterator over the entries of the dictionary.
111 #[inline]
112 pub fn iter_mut(&mut self) -> IterMut {
113 IterMut {
114 iter: self.map.iter_mut(),
115 }
116 }
117
118 /// Gets an iterator over the keys of the dictionary.
119 #[inline]
120 pub fn keys(&self) -> Keys {
121 Keys {
122 iter: self.map.keys(),
123 }
124 }
125
126 /// Gets an iterator over the values of the dictionary.
127 #[inline]
128 pub fn values(&self) -> Values {
129 Values {
130 iter: self.map.values(),
131 }
132 }
133
134 /// Gets an iterator over mutable values of the dictionary.
135 #[inline]
136 pub fn values_mut(&mut self) -> ValuesMut {
137 ValuesMut {
138 iter: self.map.values_mut(),
139 }
140 }
141}
142
143impl Default for Dictionary {
144 #[inline]
145 fn default() -> Self {
146 Dictionary {
147 map: Default::default(),
148 }
149 }
150}
151
152impl Clone for Dictionary {
153 #[inline]
154 fn clone(&self) -> Self {
155 Dictionary {
156 map: self.map.clone(),
157 }
158 }
159}
160
161impl PartialEq for Dictionary {
162 #[inline]
163 fn eq(&self, other: &Self) -> bool {
164 self.map.eq(&other.map)
165 }
166}
167
168/// Access an element of this dictionary. Panics if the given key is not present in the dictionary.
169///
170/// ```
171/// # use plist::Value;
172/// #
173/// # let val = &Value::String("".to_owned());
174/// # let _ =
175/// match *val {
176/// Value::Array(ref arr) => arr[0].as_string(),
177/// Value::Dictionary(ref dict) => dict["type"].as_string(),
178/// Value::String(ref s) => Some(s.as_str()),
179/// _ => None,
180/// }
181/// # ;
182/// ```
183impl<'a> ops::Index<&'a str> for Dictionary {
184 type Output = Value;
185
186 fn index(&self, index: &str) -> &Value {
187 self.map.index(index)
188 }
189}
190
191/// Mutably access an element of this dictionary. Panics if the given key is not present in the
192/// dictionary.
193///
194/// ```
195/// # let mut dict = plist::Dictionary::new();
196/// # dict.insert("key".to_owned(), plist::Value::Boolean(false));
197/// #
198/// dict["key"] = "value".into();
199/// ```
200impl<'a> ops::IndexMut<&'a str> for Dictionary {
201 fn index_mut(&mut self, index: &str) -> &mut Value {
202 self.map.get_mut(index).expect("no entry found for key")
203 }
204}
205
206impl Debug for Dictionary {
207 #[inline]
208 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
209 self.map.fmt(formatter)
210 }
211}
212
213/*impl ser::Serialize for Dictionary {
214 #[inline]
215 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
216 where
217 S: ser::Serializer,
218 {
219 use serde::ser::SerializeMap;
220 let mut map = try!(serializer.serialize_map(Some(self.len())));
221 for (k, v) in self {
222 try!(map.serialize_key(k));
223 try!(map.serialize_value(v));
224 }
225 map.end()
226 }
227}
228
229impl<'de> de::Deserialize<'de> for Dictionary {
230 #[inline]
231 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
232 where
233 D: de::Deserializer<'de>,
234 {
235 struct Visitor;
236
237 impl<'de> de::Visitor<'de> for Visitor {
238 type Value = Dictionary;
239
240 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
241 formatter.write_str("a map")
242 }
243
244 #[inline]
245 fn visit_unit<E>(self) -> Result<Self::Value, E>
246 where
247 E: de::Error,
248 {
249 Ok(Dictionary::new())
250 }
251
252 #[inline]
253 fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
254 where
255 V: de::MapAccess<'de>,
256 {
257 let mut values = Dictionary::new();
258
259 while let Some((key, value)) = try!(visitor.next_entry()) {
260 values.insert(key, value);
261 }
262
263 Ok(values)
264 }
265 }
266
267 deserializer.deserialize_map(Visitor)
268 }
269}*/
270
271impl FromIterator<(String, Value)> for Dictionary {
272 fn from_iter<T>(iter: T) -> Self
273 where
274 T: IntoIterator<Item = (String, Value)>,
275 {
276 Dictionary {
277 map: FromIterator::from_iter(iter),
278 }
279 }
280}
281
282impl Extend<(String, Value)> for Dictionary {
283 fn extend<T>(&mut self, iter: T)
284 where
285 T: IntoIterator<Item = (String, Value)>,
286 {
287 self.map.extend(iter);
288 }
289}
290
291macro_rules! delegate_iterator {
292 (($name:ident $($generics:tt)*) => $item:ty) => {
293 impl $($generics)* Iterator for $name $($generics)* {
294 type Item = $item;
295 #[inline]
296 fn next(&mut self) -> Option<Self::Item> {
297 self.iter.next()
298 }
299 #[inline]
300 fn size_hint(&self) -> (usize, Option<usize>) {
301 self.iter.size_hint()
302 }
303 }
304
305 /*impl $($generics)* DoubleEndedIterator for $name $($generics)* {
306 #[inline]
307 fn next_back(&mut self) -> Option<Self::Item> {
308 self.iter.next_back()
309 }
310 }*/
311
312 impl $($generics)* ExactSizeIterator for $name $($generics)* {
313 #[inline]
314 fn len(&self) -> usize {
315 self.iter.len()
316 }
317 }
318 }
319}
320
321//////////////////////////////////////////////////////////////////////////////
322
323/// A view into a single entry in a dictionary, which may either be vacant or occupied.
324/// This enum is constructed from the [`entry`] method on [`Dictionary`].
325///
326/// [`entry`]: struct.Dictionary.html#method.entry
327/// [`Dictionary`]: struct.Dictionary.html
328#[cfg(any(
329 test,
330 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
331))]
332pub enum Entry<'a> {
333 /// A vacant Entry.
334 Vacant(VacantEntry<'a>),
335 /// An occupied Entry.
336 Occupied(OccupiedEntry<'a>),
337}
338
339/// A vacant Entry. It is part of the [`Entry`] enum.
340///
341/// [`Entry`]: enum.Entry.html
342#[cfg(any(
343 test,
344 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
345))]
346pub struct VacantEntry<'a> {
347 vacant: map::VacantEntry<'a, String, Value>,
348}
349
350/// An occupied Entry. It is part of the [`Entry`] enum.
351///
352/// [`Entry`]: enum.Entry.html
353#[cfg(any(
354 test,
355 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
356))]
357pub struct OccupiedEntry<'a> {
358 occupied: map::OccupiedEntry<'a, String, Value>,
359}
360
361#[cfg(any(
362 test,
363 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
364))]
365impl<'a> Entry<'a> {
366 /// Returns a reference to this entry's key.
367 ///
368 /// # Examples
369 ///
370 /// ```
371 /// let mut dict = plist::Dictionary::new();
372 /// assert_eq!(dict.entry("serde").key(), &"serde");
373 /// ```
374 pub fn key(&self) -> &String {
375 match *self {
376 Entry::Vacant(ref e) => e.key(),
377 Entry::Occupied(ref e) => e.key(),
378 }
379 }
380
381 /// Ensures a value is in the entry by inserting the default if empty, and returns a mutable
382 /// reference to the value in the entry.
383 ///
384 /// # Examples
385 ///
386 /// ```
387 /// let mut dict = plist::Dictionary::new();
388 /// dict.entry("serde").or_insert(12.into());
389 ///
390 /// assert_eq!(dict["serde"], 12.into());
391 /// ```
392 pub fn or_insert(self, default: Value) -> &'a mut Value {
393 match self {
394 Entry::Vacant(entry) => entry.insert(default),
395 Entry::Occupied(entry) => entry.into_mut(),
396 }
397 }
398
399 /// Ensures a value is in the entry by inserting the result of the default function if empty,
400 /// and returns a mutable reference to the value in the entry.
401 ///
402 /// # Examples
403 ///
404 /// ```
405 /// let mut dict = plist::Dictionary::new();
406 /// dict.entry("serde").or_insert_with(|| "hoho".into());
407 ///
408 /// assert_eq!(dict["serde"], "hoho".into());
409 /// ```
410 pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
411 where
412 F: FnOnce() -> Value,
413 {
414 match self {
415 Entry::Vacant(entry) => entry.insert(default()),
416 Entry::Occupied(entry) => entry.into_mut(),
417 }
418 }
419}
420
421#[cfg(any(
422 test,
423 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
424))]
425impl<'a> VacantEntry<'a> {
426 /// Gets a reference to the key that would be used when inserting a value through the
427 /// VacantEntry.
428 ///
429 /// # Examples
430 ///
431 /// ```
432 /// use plist::dictionary::Entry;
433 ///
434 /// let mut dict = plist::Dictionary::new();
435 ///
436 /// match dict.entry("serde") {
437 /// Entry::Vacant(vacant) => assert_eq!(vacant.key(), &"serde"),
438 /// Entry::Occupied(_) => unimplemented!(),
439 /// }
440 /// ```
441 #[inline]
442 pub fn key(&self) -> &String {
443 self.vacant.key()
444 }
445
446 /// Sets the value of the entry with the VacantEntry's key, and returns a mutable reference
447 /// to it.
448 ///
449 /// # Examples
450 ///
451 /// ```
452 /// use plist::dictionary::Entry;
453 ///
454 /// let mut dict = plist::Dictionary::new();
455 ///
456 /// match dict.entry("serde") {
457 /// Entry::Vacant(vacant) => vacant.insert("hoho".into()),
458 /// Entry::Occupied(_) => unimplemented!(),
459 /// };
460 /// ```
461 #[inline]
462 pub fn insert(self, value: Value) -> &'a mut Value {
463 self.vacant.insert(value)
464 }
465}
466
467#[cfg(any(
468 test,
469 feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"
470))]
471impl<'a> OccupiedEntry<'a> {
472 /// Gets a reference to the key in the entry.
473 ///
474 /// # Examples
475 ///
476 /// ```
477 /// use plist::dictionary::Entry;
478 ///
479 /// let mut dict = plist::Dictionary::new();
480 /// dict.insert("serde".to_owned(), 12.into());
481 ///
482 /// match dict.entry("serde") {
483 /// Entry::Occupied(occupied) => assert_eq!(occupied.key(), &"serde"),
484 /// Entry::Vacant(_) => unimplemented!(),
485 /// }
486 /// ```
487 #[inline]
488 pub fn key(&self) -> &String {
489 self.occupied.key()
490 }
491
492 /// Gets a reference to the value in the entry.
493 ///
494 /// # Examples
495 ///
496 /// ```
497 /// use plist::Value;
498 /// use plist::dictionary::Entry;
499 ///
500 /// let mut dict = plist::Dictionary::new();
501 /// dict.insert("serde".to_owned(), 12.into());
502 ///
503 /// match dict.entry("serde") {
504 /// Entry::Occupied(occupied) => assert_eq!(occupied.get(), &Value::from(12)),
505 /// Entry::Vacant(_) => unimplemented!(),
506 /// }
507 /// ```
508 #[inline]
509 pub fn get(&self) -> &Value {
510 self.occupied.get()
511 }
512
513 /// Gets a mutable reference to the value in the entry.
514 ///
515 /// # Examples
516 ///
517 /// ```
518 /// use plist::Value;
519 /// use plist::dictionary::Entry;
520 ///
521 /// let mut dict = plist::Dictionary::new();
522 /// dict.insert("serde".to_owned(), Value::Array(vec![1.into(), 2.into(), 3.into()]));
523 ///
524 /// match dict.entry("serde") {
525 /// Entry::Occupied(mut occupied) => {
526 /// occupied.get_mut().as_array_mut().unwrap().push(4.into());
527 /// }
528 /// Entry::Vacant(_) => unimplemented!(),
529 /// }
530 ///
531 /// assert_eq!(dict["serde"].as_array().unwrap().len(), 4);
532 /// ```
533 #[inline]
534 pub fn get_mut(&mut self) -> &mut Value {
535 self.occupied.get_mut()
536 }
537
538 /// Converts the entry into a mutable reference to its value.
539 ///
540 /// # Examples
541 ///
542 /// ```
543 /// use plist::Value;
544 /// use plist::dictionary::Entry;
545 ///
546 /// let mut dict = plist::Dictionary::new();
547 /// dict.insert("serde".to_owned(), Value::Array(vec![1.into(), 2.into(), 3.into()]));
548 ///
549 /// match dict.entry("serde") {
550 /// Entry::Occupied(mut occupied) => {
551 /// occupied.into_mut().as_array_mut().unwrap().push(4.into());
552 /// }
553 /// Entry::Vacant(_) => unimplemented!(),
554 /// }
555 ///
556 /// assert_eq!(dict["serde"].as_array().unwrap().len(), 4);
557 /// ```
558 #[inline]
559 pub fn into_mut(self) -> &'a mut Value {
560 self.occupied.into_mut()
561 }
562
563 /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
564 /// the entry's old value.
565 ///
566 /// # Examples
567 ///
568 /// ```
569 /// use plist::Value;
570 /// use plist::dictionary::Entry;
571 ///
572 /// let mut dict = plist::Dictionary::new();
573 /// dict.insert("serde".to_owned(), 12.into());
574 ///
575 /// match dict.entry("serde") {
576 /// Entry::Occupied(mut occupied) => {
577 /// assert_eq!(occupied.insert(13.into()), 12.into());
578 /// assert_eq!(occupied.get(), &Value::from(13));
579 /// }
580 /// Entry::Vacant(_) => unimplemented!(),
581 /// }
582 /// ```
583 #[inline]
584 pub fn insert(&mut self, value: Value) -> Value {
585 self.occupied.insert(value)
586 }
587
588 /// Takes the value of the entry out of the dictionary, and returns it.
589 ///
590 /// # Examples
591 ///
592 /// ```
593 /// use plist::dictionary::Entry;
594 ///
595 /// let mut dict = plist::Dictionary::new();
596 /// dict.insert("serde".to_owned(), 12.into());
597 ///
598 /// match dict.entry("serde") {
599 /// Entry::Occupied(occupied) => assert_eq!(occupied.remove(), 12.into()),
600 /// Entry::Vacant(_) => unimplemented!(),
601 /// }
602 /// ```
603 #[inline]
604 pub fn remove(self) -> Value {
605 self.occupied.remove()
606 }
607}
608
609//////////////////////////////////////////////////////////////////////////////
610
611impl<'a> IntoIterator for &'a Dictionary {
612 type Item = (&'a String, &'a Value);
613 type IntoIter = Iter<'a>;
614 #[inline]
615 fn into_iter(self) -> Self::IntoIter {
616 Iter {
617 iter: self.map.iter(),
618 }
619 }
620}
621
622/// An iterator over a plist::Dictionary's entries.
623pub struct Iter<'a> {
624 iter: IterImpl<'a>,
625}
626
627type IterImpl<'a> = map::Iter<'a, String, Value>;
628
629delegate_iterator!((Iter<'a>) => (&'a String, &'a Value));
630
631//////////////////////////////////////////////////////////////////////////////
632
633impl<'a> IntoIterator for &'a mut Dictionary {
634 type Item = (&'a String, &'a mut Value);
635 type IntoIter = IterMut<'a>;
636 #[inline]
637 fn into_iter(self) -> Self::IntoIter {
638 IterMut {
639 iter: self.map.iter_mut(),
640 }
641 }
642}
643
644/// A mutable iterator over a plist::Dictionary's entries.
645pub struct IterMut<'a> {
646 iter: map::IterMut<'a, String, Value>,
647}
648
649delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value));
650
651//////////////////////////////////////////////////////////////////////////////
652
653impl IntoIterator for Dictionary {
654 type Item = (String, Value);
655 type IntoIter = IntoIter;
656 #[inline]
657 fn into_iter(self) -> Self::IntoIter {
658 IntoIter {
659 iter: self.map.into_iter(),
660 }
661 }
662}
663
664/// An owning iterator over a plist::Dictionary's entries.
665pub struct IntoIter {
666 iter: map::IntoIter<String, Value>,
667}
668
669delegate_iterator!((IntoIter) => (String, Value));
670
671//////////////////////////////////////////////////////////////////////////////
672
673/// An iterator over a plist::Dictionary's keys.
674pub struct Keys<'a> {
675 iter: map::Keys<'a, String, Value>,
676}
677
678delegate_iterator!((Keys<'a>) => &'a String);
679
680//////////////////////////////////////////////////////////////////////////////
681
682/// An iterator over a plist::Dictionary's values.
683pub struct Values<'a> {
684 iter: map::Values<'a, String, Value>,
685}
686
687delegate_iterator!((Values<'a>) => &'a Value);
688
689//////////////////////////////////////////////////////////////////////////////
690
691/// A mutable iterator over a plist::Dictionary's values.
692pub struct ValuesMut<'a> {
693 iter: map::ValuesMut<'a, String, Value>,
694}
695
696delegate_iterator!((ValuesMut<'a>) => &'a mut Value);