1use futures::{stream::unfold, FutureExt, Stream, StreamExt};
10use futures_timer::Delay;
11use linked_hash_set::LinkedHashSet;
12
13use std::{hash::Hash, num::NonZeroUsize, time::Duration};
14
15pub fn interval(duration: Duration) -> impl Stream<Item = ()> + Unpin {
17 unfold((), move |_| Delay::new(duration).map(|_| Some(((), ())))).map(drop)
18}
19
20#[derive(Debug, Clone)]
24pub struct LruHashSet<T: Hash + Eq> {
25 set: LinkedHashSet<T>,
26 limit: NonZeroUsize,
27}
28
29impl<T: Hash + Eq> LruHashSet<T> {
30 pub fn new(limit: NonZeroUsize) -> Self {
32 Self { set: LinkedHashSet::new(), limit }
33 }
34
35 pub fn insert(&mut self, e: T) -> bool {
41 if self.set.insert(e) {
42 if self.set.len() == usize::from(self.limit) {
43 self.set.pop_front(); }
45 return true;
46 }
47 false
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn maintains_limit() {
57 let three = NonZeroUsize::new(3).unwrap();
58 let mut set = LruHashSet::<u8>::new(three);
59
60 assert!(set.insert(1));
62 assert_eq!(vec![&1], set.set.iter().collect::<Vec<_>>());
63
64 assert!(set.insert(2));
66 assert_eq!(vec![&1, &2], set.set.iter().collect::<Vec<_>>());
67
68 assert!(!set.insert(1));
70 assert_eq!(vec![&2, &1], set.set.iter().collect::<Vec<_>>());
71
72 assert!(set.insert(3));
74 assert_eq!(vec![&1, &3], set.set.iter().collect::<Vec<_>>());
75 }
76}