frequency-btreemap 1.0.0

A counter for observations of things, backed by a BTreeMap.
Documentation
//! The [`Frequency`][frequency] trait represents types that keep track of the 
//! observed counts of items. The [`BTreeMapFrequency`][btreemapfrequency] type
//! is a frequency counter backed by a [`BTreeMap`][btreemap].
//!
//! # Usage
//! Add [`frequency`][freq_crate] and `frequency-btreemap` to your `Cargo.toml`:
//!
//! ```
//! [dependencies]
//! frequency = "^1.0.0"
//! frequency-btreemap = "^1.0.0"
//! ```
//!
//! Import both [`Frequency`][frequency] and 
//! [`BTreeMapFrequency`][btreemapfrequency]:
//!
//! ```
//! extern crate frequency;
//! extern crate frequency_btreemap;
//!
//! use frequency::Frequency;
//! use frequency_btreemap::BTreeMapFrequency;
//! ```
//!
//! [freq_crate]: https://docs.rs/frequency/~1/
//! [frequency]: https://docs.rs/frequency/~1/frequency/trait.Frequency.html
//! [btreemapfrequency]: struct.BTreeMapFrequency.html
//! [btreemap]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html

extern crate frequency;
extern crate num_traits;

use frequency::Frequency;
use num_traits::{Num, Zero, One};
use std::iter::FromIterator;
use std::collections::btree_map::{Iter, Keys, Values, BTreeMap};

/// A frequency counter backed by a [`BTreeMap`][btreemap].
/// [btreemap]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html.
pub struct BTreeMapFrequency<T, N=usize>
    where T: Ord,
          N: Num
{
    frequency: BTreeMap<T, N>,
}

impl<'t, T, N> Frequency<'t, T> for BTreeMapFrequency<T, N>
    where T: 't + Ord,
          N: 't + Num + Clone
{
    type N      = N;
    type Iter   = Iter<'t, T, Self::N>;
    type Items  = Keys<'t, T, Self::N>;
    type Counts = Values<'t, T, Self::N>;

    #[inline]
    fn count(&self, key: &T) -> Self::N
    {
        self.frequency.get(key).cloned().unwrap_or_else(Zero::zero)
    }

    #[inline]
    fn increment(&mut self, value: T) {
        let value = self.frequency.entry(value).or_insert_with(Zero::zero);
        *value = value.clone() + One::one();
    }

    #[inline]
    fn iter(&'t self) -> Self::Iter {
        self.frequency.iter()
    }

    #[inline]
    fn items(&'t self) -> Self::Items {
        self.frequency.keys()
    }

    #[inline]
    fn counts(&'t self) -> Self::Counts {
        self.frequency.values()
    }
}

impl<T, N> BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num
{
    /// Creates an empty `BTreeMapFrequency`, a frequency counter backed
    /// by a BTreeMap.
    #[inline]
    pub fn new() -> BTreeMapFrequency<T,N> {
        Default::default()
    }

    /// Returns the number of elements that have been counted.
    #[inline]
    pub fn len(&self) -> usize {
        self.frequency.len()
    }

    /// Returns true if the counter contains no elements.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }
}

impl<T, N> Default for BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num
{
    /// Creates an empty `BTreeMapFrequency<T, V, S>`, a frequency counter backed
    /// by a BTreeMap with the `Default` value for the hasher.
    fn default() -> BTreeMapFrequency<T,N> {
        BTreeMapFrequency {
            frequency: Default::default()
        }
    }
}

impl<T, N> Extend<T> for BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num + Clone
{
    fn extend<I: IntoIterator<Item=T>>(&mut self, iter: I) {
        for k in iter {
            self.increment(k);
        }
    }
}

impl<T, N> FromIterator<T> for BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num + Clone
{
    fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
        let mut frequency = BTreeMapFrequency::new();
        frequency.extend(iter);
        frequency
    }
}

impl<'t, T, N> IntoIterator for &'t BTreeMapFrequency<T, N>
    where T: 't + Ord,
          N: 't + Num + Clone
{
    type Item = <<BTreeMapFrequency<T, N> as Frequency<'t, T>>::Iter as Iterator>::Item;
    type IntoIter = <BTreeMapFrequency<T, N> as Frequency<'t, T>>::Iter;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<T, N> AsRef<BTreeMap<T, N>> for BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num
{
    fn as_ref(&self) -> &BTreeMap<T, N> {
        &self.frequency
    }
}

impl<T, N> AsMut<BTreeMap<T, N>> for BTreeMapFrequency<T, N>
    where T: Ord,
          N: Num
{
    fn as_mut(&mut self) -> &mut BTreeMap<T, N> {
        &mut self.frequency
    }
}