Skip to content

Commit

Permalink
Merge pull request #88 from Mingun/clone+debug
Browse files Browse the repository at this point in the history
Implementation of Clone, Debug and documentation for structures
  • Loading branch information
cuviper authored Feb 20, 2019
2 parents ee07695 + 33fd850 commit d8e5225
Show file tree
Hide file tree
Showing 4 changed files with 317 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "indexmap"
version = "1.0.2"
version = "1.1.0"
authors = [
"bluss",
"Josh Stone <[email protected]>"
Expand Down Expand Up @@ -31,7 +31,7 @@ bench = false
serde = { version = "1.0", optional = true }

[dev-dependencies]
itertools = "0.7.0"
itertools = "0.7.0" # 0.8 not compiles on Rust 1.18
rand = "0.4"
quickcheck = { version = "0.6", default-features = false }
fnv = "1.0"
Expand Down
8 changes: 8 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ Ideas that we already did
Recent Changes
==============

- 1.1.0

- Implemented ``Clone`` for ``map::{Iter, Keys, Values}`` and
``set::{Difference, Intersection, Iter, SymmetricDifference, Union}``

- Implemented ``Debug`` for ``map::{Entry, IntoIter, Iter, Keys, Values}`` and
``set::{Difference, Intersection, IntoIter, Iter, SymmetricDifference, Union}``

- 1.0.2

- The new methods ``IndexMap::insert_full`` and ``IndexSet::insert_full`` are
Expand Down
178 changes: 178 additions & 0 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,27 @@ impl<'a, K, V> Entry<'a, K, V> {
}
}

impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Entry<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Entry::Vacant(ref v) => {
f.debug_tuple("Entry")
.field(v)
.finish()
}
Entry::Occupied(ref o) => {
f.debug_tuple("Entry")
.field(o)
.finish()
}
}
}
}

/// A view into an occupied entry in a `IndexMap`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
map: &'a mut OrderMapCore<K, V>,
key: K,
Expand Down Expand Up @@ -625,7 +646,19 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
}
}

impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for OccupiedEntry<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("key", self.key())
.field("value", self.get())
.finish()
}
}

/// A view into a vacant entry in a `IndexMap`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
pub struct VacantEntry<'a, K: 'a, V: 'a> {
map: &'a mut OrderMapCore<K, V>,
key: K,
Expand Down Expand Up @@ -657,6 +690,14 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
}
}

impl<'a, K: 'a + fmt::Debug, V: 'a> fmt::Debug for VacantEntry<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("VacantEntry")
.field(self.key())
.finish()
}
}

impl<K, V, S> IndexMap<K, V, S>
where K: Hash + Eq,
S: BuildHasher,
Expand Down Expand Up @@ -1455,6 +1496,13 @@ use std::slice::Iter as SliceIter;
use std::slice::IterMut as SliceIterMut;
use std::vec::IntoIter as VecIntoIter;

/// An iterator over the keys of a `IndexMap`.
///
/// This `struct` is created by the [`keys`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`keys`]: struct.IndexMap.html#method.keys
/// [`IndexMap`]: struct.IndexMap.html
pub struct Keys<'a, K: 'a, V: 'a> {
pub(crate) iter: SliceIter<'a, Bucket<K, V>>,
}
Expand All @@ -1477,6 +1525,28 @@ impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
}
}

// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<'a, K, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> {
Keys { iter: self.iter.clone() }
}
}

impl<'a, K: fmt::Debug, V> fmt::Debug for Keys<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
.entries(self.clone())
.finish()
}
}

/// An iterator over the values of a `IndexMap`.
///
/// This `struct` is created by the [`values`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`values`]: struct.IndexMap.html#method.values
/// [`IndexMap`]: struct.IndexMap.html
pub struct Values<'a, K: 'a, V: 'a> {
iter: SliceIter<'a, Bucket<K, V>>,
}
Expand All @@ -1499,6 +1569,28 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
}
}

// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<'a, K, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> {
Values { iter: self.iter.clone() }
}
}

impl<'a, K, V: fmt::Debug> fmt::Debug for Values<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
.entries(self.clone())
.finish()
}
}

/// A mutable iterator over the values of a `IndexMap`.
///
/// This `struct` is created by the [`values_mut`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`values_mut`]: struct.IndexMap.html#method.values_mut
/// [`IndexMap`]: struct.IndexMap.html
pub struct ValuesMut<'a, K: 'a, V: 'a> {
iter: SliceIterMut<'a, Bucket<K, V>>,
}
Expand All @@ -1521,6 +1613,13 @@ impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
}
}

/// An iterator over the entries of a `IndexMap`.
///
/// This `struct` is created by the [`iter`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`iter`]: struct.IndexMap.html#method.iter
/// [`IndexMap`]: struct.IndexMap.html
pub struct Iter<'a, K: 'a, V: 'a> {
iter: SliceIter<'a, Bucket<K, V>>,
}
Expand All @@ -1543,6 +1642,28 @@ impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
}
}

// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<'a, K, V> Clone for Iter<'a, K, V> {
fn clone(&self) -> Iter<'a, K, V> {
Iter { iter: self.iter.clone() }
}
}

impl<'a, K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'a, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list()
.entries(self.clone())
.finish()
}
}

/// A mutable iterator over the entries of a `IndexMap`.
///
/// This `struct` is created by the [`iter_mut`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`iter_mut`]: struct.IndexMap.html#method.iter_mut
/// [`IndexMap`]: struct.IndexMap.html
pub struct IterMut<'a, K: 'a, V: 'a> {
iter: SliceIterMut<'a, Bucket<K, V>>,
}
Expand All @@ -1565,6 +1686,13 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
}
}

/// An owning iterator over the entries of a `IndexMap`.
///
/// This `struct` is created by the [`into_iter`] method on [`IndexMap`]
/// (provided by the `IntoIterator` trait). See its documentation for more.
///
/// [`into_iter`]: struct.IndexMap.html#method.into_iter
/// [`IndexMap`]: struct.IndexMap.html
pub struct IntoIter<K, V> {
pub(crate) iter: VecIntoIter<Bucket<K, V>>,
}
Expand All @@ -1587,6 +1715,20 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> {
}
}

impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let iter = self.iter.as_slice().iter().map(Bucket::refs);
f.debug_list().entries(iter).finish()
}
}

/// A draining iterator over the entries of a `IndexMap`.
///
/// This `struct` is created by the [`drain`] method on [`IndexMap`]. See its
/// documentation for more.
///
/// [`drain`]: struct.IndexMap.html#method.drain
/// [`IndexMap`]: struct.IndexMap.html
pub struct Drain<'a, K, V> where K: 'a, V: 'a {
pub(crate) iter: ::std::vec::Drain<'a, Bucket<K, V>>
}
Expand Down Expand Up @@ -2047,4 +2189,40 @@ mod tests {

assert_eq!(&mut TestEnum::DefaultValue, map.entry(2).or_default());
}

#[test]
fn keys() {
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let map: IndexMap<_, _> = vec.into_iter().collect();
let keys: Vec<_> = map.keys().cloned().collect();
assert_eq!(keys.len(), 3);
assert!(keys.contains(&1));
assert!(keys.contains(&2));
assert!(keys.contains(&3));
}

#[test]
fn values() {
let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
let map: IndexMap<_, _> = vec.into_iter().collect();
let values: Vec<_> = map.values().cloned().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&'a'));
assert!(values.contains(&'b'));
assert!(values.contains(&'c'));
}

#[test]
fn values_mut() {
let vec = vec![(1, 1), (2, 2), (3, 3)];
let mut map: IndexMap<_, _> = vec.into_iter().collect();
for value in map.values_mut() {
*value = (*value) * 2
}
let values: Vec<_> = map.values().cloned().collect();
assert_eq!(values.len(), 3);
assert!(values.contains(&2));
assert!(values.contains(&4));
assert!(values.contains(&6));
}
}
Loading

0 comments on commit d8e5225

Please sign in to comment.