orphanage 0.5.6

Random collection of stuff that is still searching for a home.
Documentation
use std::hash::Hash;

pub use hashbrown::HashSet;

pub struct Diff<'a, T> {
  pub added: HashSet<&'a T>,
  pub removed: HashSet<&'a T>,
  pub unchanged: HashSet<&'a T>
}

impl<T> Diff<'_, T> {
  /// Returns `true` if the sets that were diff'd have changed.
  #[must_use]
  pub fn changed(&self) -> bool {
    !self.added.is_empty() || !self.removed.is_empty()
  }
}

/// Calculate changes between two sets.
///
/// Returns a struct containing:
/// - `added`, containing elements that exist in new set but not in old.
/// - `removed`, containig elements that exist in old set but not in new.
/// - `unchaned`, containing elements that exists in both old and new sets.
///
/// ```
/// use orphanage::setops::{HashSet, changes};
///
/// let old: HashSet<u32> = [1, 2].into_iter().collect();
/// let new: HashSet<u32> = [2, 3].into_iter().collect();
///
/// let diff = changes(&old, &new);
///
/// let mut added: Vec<u32> = diff.added.into_iter().copied().collect();
/// added.sort_unstable();
/// let mut removed: Vec<u32> = diff.removed.into_iter().copied().collect();
/// removed.sort_unstable();
/// let mut unchanged: Vec<u32> = diff.unchanged.into_iter().copied().collect();
/// unchanged.sort_unstable();
///
/// assert_eq!(&added, &[3]);
/// assert_eq!(&removed, &[1]);
/// assert_eq!(&unchanged, &[2]);
/// ```
#[must_use]
pub fn changes<'a, T>(old: &'a HashSet<T>, new: &'a HashSet<T>) -> Diff<'a, T>
where
  T: Hash + Eq
{
  let added: HashSet<_> = new.difference(old).collect();
  let removed: HashSet<_> = old.difference(new).collect();
  let unchanged: HashSet<_> = old.intersection(new).collect();

  Diff {
    added,
    removed,
    unchanged
  }
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :