-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from chris-ha458/refactor
refactor tests and impls into distinct modules
- Loading branch information
Showing
16 changed files
with
1,227 additions
and
1,139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
mod add_iterable; | ||
mod add_self; | ||
mod create; | ||
mod deref; | ||
mod extend; | ||
mod from_iterator; | ||
mod index; | ||
mod intersection; | ||
mod into_iterator; | ||
mod sub_iterable; | ||
mod sub_self; | ||
mod union; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use crate::Counter; | ||
|
||
use num_traits::{One, Zero}; | ||
|
||
use std::hash::Hash; | ||
use std::ops::{Add, AddAssign}; | ||
|
||
impl<I, T, N> Add<I> for Counter<T, N> | ||
where | ||
I: IntoIterator<Item = T>, | ||
T: Hash + Eq, | ||
N: AddAssign + Zero + One, | ||
{ | ||
type Output = Self; | ||
/// Consume `self` producing a `Counter` like `self` updated with the counts of | ||
/// the elements of `I`. | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let counter = Counter::init("abbccc".chars()); | ||
/// | ||
/// let new_counter = counter + "aeeeee".chars(); | ||
/// let expected: HashMap<char, usize> = [('a', 2), ('b', 2), ('c', 3), ('e', 5)] | ||
/// .iter().cloned().collect(); | ||
/// assert_eq!(new_counter.into_map(), expected); | ||
/// ``` | ||
fn add(mut self, rhs: I) -> Self::Output { | ||
self.update(rhs); | ||
self | ||
} | ||
} | ||
|
||
impl<I, T, N> AddAssign<I> for Counter<T, N> | ||
where | ||
I: IntoIterator<Item = T>, | ||
T: Hash + Eq, | ||
N: AddAssign + Zero + One, | ||
{ | ||
/// Directly add the counts of the elements of `I` to `self`. | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let mut counter = Counter::init("abbccc".chars()); | ||
/// | ||
/// counter += "aeeeee".chars(); | ||
/// let expected: HashMap<char, usize> = [('a', 2), ('b', 2), ('c', 3), ('e', 5)] | ||
/// .iter().cloned().collect(); | ||
/// assert_eq!(counter.into_map(), expected); | ||
/// ``` | ||
fn add_assign(&mut self, rhs: I) { | ||
self.update(rhs); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use crate::Counter; | ||
|
||
use num_traits::Zero; | ||
|
||
use std::hash::Hash; | ||
use std::ops::{Add, AddAssign}; | ||
|
||
impl<T, N> Add for Counter<T, N> | ||
where | ||
T: Clone + Hash + Eq, | ||
N: AddAssign + Zero, | ||
{ | ||
type Output = Counter<T, N>; | ||
|
||
/// Add two counters together. | ||
/// | ||
/// `out = c + d;` -> `out[x] == c[x] + d[x]` for all `x` | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let c = "aaab".chars().collect::<Counter<_>>(); | ||
/// let d = "abb".chars().collect::<Counter<_>>(); | ||
/// | ||
/// let e = c + d; | ||
/// | ||
/// let expect = [('a', 4), ('b', 3)].iter().cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(e.into_map(), expect); | ||
/// ``` | ||
fn add(mut self, rhs: Counter<T, N>) -> Self::Output { | ||
self += rhs; | ||
self | ||
} | ||
} | ||
|
||
impl<T, N> AddAssign for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: Zero + AddAssign, | ||
{ | ||
/// Add another counter to this counter. | ||
/// | ||
/// `c += d;` -> `c[x] += d[x]` for all `x` | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let mut c = "aaab".chars().collect::<Counter<_>>(); | ||
/// let d = "abb".chars().collect::<Counter<_>>(); | ||
/// | ||
/// c += d; | ||
/// | ||
/// let expect = [('a', 4), ('b', 3)].iter().cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(c.into_map(), expect); | ||
/// ``` | ||
fn add_assign(&mut self, rhs: Self) { | ||
for (key, value) in rhs.map { | ||
let entry = self.map.entry(key).or_insert_with(N::zero); | ||
*entry += value; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use crate::Counter; | ||
|
||
use num_traits::Zero; | ||
|
||
use std::collections::HashMap; | ||
use std::hash::Hash; | ||
|
||
impl<T, N> Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: Zero, | ||
{ | ||
/// Create a new, empty `Counter` | ||
pub fn new() -> Self { | ||
Counter { | ||
map: HashMap::new(), | ||
zero: N::zero(), | ||
} | ||
} | ||
} | ||
|
||
impl<T, N> Default for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: Default, | ||
{ | ||
fn default() -> Self { | ||
Self { | ||
map: Default::default(), | ||
zero: Default::default(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
use crate::Counter; | ||
|
||
use std::collections::HashMap; | ||
use std::hash::Hash; | ||
use std::ops::{Deref, DerefMut}; | ||
|
||
type CounterMap<T, N> = HashMap<T, N>; | ||
|
||
impl<T, N> Deref for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
{ | ||
type Target = CounterMap<T, N>; | ||
fn deref(&self) -> &CounterMap<T, N> { | ||
&self.map | ||
} | ||
} | ||
|
||
impl<T, N> DerefMut for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
{ | ||
fn deref_mut(&mut self) -> &mut CounterMap<T, N> { | ||
&mut self.map | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use crate::Counter; | ||
|
||
use num_traits::{One, Zero}; | ||
|
||
use std::hash::Hash; | ||
use std::ops::AddAssign; | ||
|
||
impl<T, N> Extend<T> for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: AddAssign + Zero + One, | ||
{ | ||
/// Extend a `Counter` with an iterator of items. | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let mut counter = "abbccc".chars().collect::<Counter<_>>(); | ||
/// counter.extend("bccddd".chars()); | ||
/// let expect = [('a', 1), ('b', 3), ('c', 5), ('d', 3)].iter().cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(counter.into_map(), expect); | ||
/// ``` | ||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { | ||
self.update(iter); | ||
} | ||
} | ||
|
||
impl<T, N> Extend<(T, N)> for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: AddAssign + Zero, | ||
{ | ||
/// Extend a counter with `(item, count)` tuples. | ||
/// | ||
/// The counts of duplicate items are summed. | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let mut counter = "abbccc".chars().collect::<Counter<_>>(); | ||
/// counter.extend([('a', 1), ('b', 2), ('c', 3), ('a', 4)].iter().cloned()); | ||
/// let expect = [('a', 6), ('b', 4), ('c', 6)].iter() | ||
/// .cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(counter.into_map(), expect); | ||
/// ``` | ||
fn extend<I: IntoIterator<Item = (T, N)>>(&mut self, iter: I) { | ||
for (item, item_count) in iter { | ||
let entry = self.map.entry(item).or_insert_with(N::zero); | ||
*entry += item_count; | ||
} | ||
} | ||
} | ||
|
||
impl<'a, T: 'a, N: 'a> Extend<(&'a T, &'a N)> for Counter<T, N> | ||
where | ||
T: Hash + Eq + Clone, | ||
N: AddAssign + Zero + Clone, | ||
{ | ||
/// Extend a counter with `(item, count)` tuples. | ||
/// | ||
/// You can extend a `Counter` with another `Counter`: | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let mut counter = "abbccc".chars().collect::<Counter<_>>(); | ||
/// let another = "bccddd".chars().collect::<Counter<_>>(); | ||
/// counter.extend(&another); | ||
/// let expect = [('a', 1), ('b', 3), ('c', 5), ('d', 3)].iter() | ||
/// .cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(counter.into_map(), expect); | ||
/// ``` | ||
fn extend<I: IntoIterator<Item = (&'a T, &'a N)>>(&mut self, iter: I) { | ||
for (item, item_count) in iter { | ||
let entry = self.map.entry(item.clone()).or_insert_with(N::zero); | ||
*entry += item_count.clone(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
use crate::Counter; | ||
|
||
use num_traits::{One, Zero}; | ||
|
||
use std::hash::Hash; | ||
use std::iter; | ||
use std::ops::AddAssign; | ||
|
||
impl<T, N> Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: AddAssign + Zero + One, | ||
{ | ||
/// Create a new `Counter` initialized with the given iterable. | ||
pub fn init<I>(iterable: I) -> Self | ||
where | ||
I: IntoIterator<Item = T>, | ||
{ | ||
let mut counter = Counter::new(); | ||
counter.update(iterable); | ||
counter | ||
} | ||
} | ||
|
||
impl<T, N> iter::FromIterator<T> for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: AddAssign + Zero + One, | ||
{ | ||
/// Produce a `Counter` from an iterator of items. This is called automatically | ||
/// by [`Iterator::collect()`]. | ||
/// | ||
/// [`Iterator::collect()`]: | ||
/// https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.collect | ||
/// | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let counter = "abbccc".chars().collect::<Counter<_>>(); | ||
/// let expect = [('a', 1), ('b', 2), ('c', 3)].iter().cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(counter.into_map(), expect); | ||
/// ``` | ||
/// | ||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { | ||
Counter::<T, N>::init(iter) | ||
} | ||
} | ||
|
||
impl<T, N> iter::FromIterator<(T, N)> for Counter<T, N> | ||
where | ||
T: Hash + Eq, | ||
N: AddAssign + Zero, | ||
{ | ||
/// Creates a counter from `(item, count)` tuples. | ||
/// | ||
/// The counts of duplicate items are summed. | ||
/// ```rust | ||
/// # use counter::Counter; | ||
/// # use std::collections::HashMap; | ||
/// let counter = [('a', 1), ('b', 2), ('c', 3), ('a', 4)].iter() | ||
/// .cloned().collect::<Counter<_>>(); | ||
/// let expect = [('a', 5), ('b', 2), ('c', 3)].iter() | ||
/// .cloned().collect::<HashMap<_, _>>(); | ||
/// assert_eq!(counter.into_map(), expect); | ||
/// ``` | ||
fn from_iter<I: IntoIterator<Item = (T, N)>>(iter: I) -> Self { | ||
let mut cnt = Counter::new(); | ||
for (item, item_count) in iter { | ||
let entry = cnt.map.entry(item).or_insert_with(N::zero); | ||
*entry += item_count; | ||
} | ||
cnt | ||
} | ||
} |
Oops, something went wrong.