Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of Clone, Debug and documentation for structures #88

Merged
merged 4 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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