You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.1 KiB

//! Lagging iterators / (todo) streams.
use super::*;
use std::time::Duration;
use tokio::time;
/// A lagged iterator
#[derive(Debug, Clone)]
pub struct Lag<I: ?Sized, T>(Duration, I)
where I: Iterator<Item=T>;
impl<I: ?Sized, T> Lag<I, T>
where I: Iterator<Item=T>
{
/// Set the lag duration
#[inline] pub fn set_duration(&mut self, dur: Duration)
{
self.0 = dur;
}
/// Get the lag duration
#[inline] pub fn duration(&self) -> Duration
{
self.0
}
}
impl<I, T> Lag<I, T>
where I: Iterator<Item=T>
{
/// Consume into the inner iterator
#[inline] pub fn into_inner(self) -> I
{
self.1
}
}
pub trait LagStreamExt: Stream + Sized
{
/// Throttle a `Stream` by this duration.
fn lag(self, dur: Duration) -> time::Throttle<Self>;
}
impl<T> LagStreamExt for T
where T: Stream
{
#[inline] fn lag(self, dur: Duration) -> time::Throttle<Self>
{
time::throttle(dur, self)
}
}
pub trait LagIterExt: Iterator
{
fn lag_sync(self, dur: Duration) -> Lag<Self, Self::Item>;
}
impl<I> LagIterExt for I
where I: Iterator
{
#[inline] fn lag_sync(self, dur: Duration) -> Lag<Self, Self::Item>
{
Lag(dur, self)
}
}
impl<I: ?Sized, T> Iterator for Lag<I, T>
where I: Iterator<Item=T>
{
type Item = T;
fn next(&mut self) -> Option<Self::Item>
{
std::thread::sleep(self.0);
self.1.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.1.size_hint()
}
}
impl<I: ?Sized, T> FusedIterator for Lag<I, T>
where I: Iterator<Item=T> + FusedIterator{}
impl<I: ?Sized, T> ExactSizeIterator for Lag<I, T>
where I: Iterator<Item=T> + ExactSizeIterator{}
impl<I: ?Sized, T> DoubleEndedIterator for Lag<I, T>
where I: Iterator<Item=T> + DoubleEndedIterator
{
fn next_back(&mut self) -> Option<Self::Item>
{
std::thread::sleep(self.0);
self.1.next()
}
}
pub trait JitterExt<T>
{
/// Produce a random value between `self.0` and `self.1` inclusive
fn jitter(self) -> T;
}
impl<T> JitterExt<T> for (T, T)
where T: rand::distributions::uniform::SampleUniform
{
fn jitter(self) -> T
{
util::jitter(self.0, self.1)
}
}