use std::clone::Clone;
use std::cmp::Eq;
use std::collections::HashSet;
use std::hash::Hash;
use std::iter::Iterator;
#[derive(Debug)]
pub struct WrappingHashSet<T>
where
T: Eq + Hash,
{
hashset: HashSet<T>,
keys: Vec<T>,
pos: usize,
}
pub struct Iter<'i, T: 'i>
where
T: Eq + Hash,
{
whs: &'i mut WrappingHashSet<T>,
count: usize,
}
impl<'i, T> Iterator for Iter<'i, T>
where
T: Eq + Hash + Clone,
{
type Item = T;
fn next(&mut self) -> Option<T> {
if self.whs.pos >= self.whs.hashset.len() {
self.whs.pos = 0;
}
self.count += 1;
if self.count > self.whs.hashset.len() {
self.count = 0;
return None;
}
self.whs.pos += 1;
Some(self.whs.keys[self.whs.pos - 1].clone())
}
}
impl<T> WrappingHashSet<T>
where
T: Eq + Hash + Clone,
{
pub fn new() -> WrappingHashSet<T> {
WrappingHashSet {
hashset: HashSet::new(),
keys: Vec::new(),
pos: 0,
}
}
pub fn iter<'i>(&'i mut self) -> Iter<'i, T> {
Iter {
whs: self,
count: 0,
}
}
pub fn insert(&mut self, key: T) -> bool {
if self.hashset.insert(key.clone()) {
self.keys.push(key);
return true;
}
return false;
}
pub fn remove<'b>(&mut self, key: &'b T) -> bool {
if self.hashset.remove(key) {
self.keys = Vec::new();
for k in self.hashset.iter() {
self.keys.push(k.clone())
}
return true;
}
return false;
}
}
#[test]
fn test_wrapping_hashset() {
let mut hs: WrappingHashSet<&str> = WrappingHashSet::new();
let mut keys_as_found: Vec<&str> = Vec::new();
hs.insert("foo");
hs.insert("bar");
hs.insert("baz");
{
for i in hs.iter() {
keys_as_found.push(i);
}
let mut z = keys_as_found.clone();
z.sort();
assert_eq!("bar", z[0]);
assert_eq!("baz", z[1]);
assert_eq!("foo", z[2]);
}
{
for i in hs.iter() {
assert_eq!(keys_as_found[0], i, "First Iter returns first element");
break;
}
}
{
for i in hs.iter() {
assert_eq!(
keys_as_found[1], i,
"Second Iter returns second element first"
);
break;
}
}
{
for i in hs.iter() {
assert_eq!(
keys_as_found[2], i,
"Third Iter returns third element first"
);
break;
}
}
{
for i in hs.iter() {
assert_eq!(
keys_as_found[0], i,
"Fourth Iter returns first element first"
);
break;
}
}
{
let mut iter = hs.iter();
assert_eq!(Some(keys_as_found[1]), iter.next());
assert_eq!(Some(keys_as_found[2]), iter.next());
assert_eq!(Some(keys_as_found[0]), iter.next());
assert_eq!(None, iter.next(), "Should wrap only once");
}
{
let mut iter = hs.iter();
assert_eq!(Some(keys_as_found[1]), iter.next());
assert_eq!(Some(keys_as_found[2]), iter.next());
assert_eq!(Some(keys_as_found[0]), iter.next());
assert_eq!(None, iter.next(), "Should repeat");
}
{
let mut iter = hs.iter();
assert_eq!(Some(keys_as_found[1]), iter.next());
}
{
let mut iter = hs.iter();
assert_eq!(Some(keys_as_found[2]), iter.next());
}
hs.remove(&keys_as_found[1]);
{
let mut j = 0;
for i in hs.iter() {
assert_ne!(keys_as_found[1], i, "Elements should not reappear");
j = j + 1;
}
assert_eq!(2, j, "We should only iterate the leftover elements");
}
}
#[test]
fn test_empty() {
let mut hs: WrappingHashSet<&str> = WrappingHashSet::new();
{
let mut hsiter = hs.iter();
assert_eq!(None, hsiter.next());
}
hs.insert("one");
hs.insert("two");
let mut hsiter = hs.iter();
assert_eq!(Some("one"), hsiter.next());
assert_eq!(Some("two"), hsiter.next());
assert_eq!(None, hsiter.next());
}
#[test]
fn test_one_item() {
let mut hs: WrappingHashSet<&str> = WrappingHashSet::new();
hs.insert("onething");
{
let mut hsiter = hs.iter();
assert_eq!(Some("onething"), hsiter.next());
assert_eq!(None, hsiter.next());
}
{
let mut _hsunused = hs.iter();
}
{
let mut hsiter = hs.iter();
assert_eq!(Some("onething"), hsiter.next());
assert_eq!(None, hsiter.next());
}
}