//! Throttle provider
use std ::iter ;
use std ::num ::NonZeroUsize ;
/// Buffer size for `DefaultBufferSize`
pub const DEFAULT_BUFFER_SIZE : usize = 4096 ;
/// `BufferProvider` that only provides the `DEFAULT_BUFFER_SIZE`.
#[ derive(Debug, Clone, PartialEq, Eq, Hash, Copy) ]
pub struct DefaultBufferSize ;
/// `BufferProvider` that never provides a chunking buffer size.
///
/// Therefore, buffers are always consumed as-is.
#[ derive(Debug, Clone, PartialEq, Eq, Hash) ]
pub struct NoBufferProvider ;
impl BufferProvider for NoBufferProvider
{
#[ inline(always) ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
None
}
}
impl BufferProvider for DefaultBufferSize
{
#[ inline(always) ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
NonZeroUsize ::new ( DEFAULT_BUFFER_SIZE )
}
}
/// The type that dictates the amount of time to wait between each read.
pub type Duration = std ::time ::Duration ;
pub trait BufferProvider
{
/// Try to get the next buffer size.
///
/// # Implementations
/// * *Should* always return `Some` *at least* once with no upper bound on the number of `Some`s that can be returned.
/// * *Should* return `Some` until there are no more left (*can* be infinite.)
/// * After a `None`, there **must never** be another non-`None` value.
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > ;
}
/// Iterator adaptor for `BufferProvider`'s `gen_next_buffer_size()`.
#[ derive(Debug, Clone) ]
pub struct BufferProviderIter < T : ? Sized > ( T ) ;
impl < T : ? Sized + BufferProvider > Iterator for BufferProviderIter < T >
{
type Item = NonZeroUsize ;
#[ inline ]
fn next ( & mut self ) -> Option < Self ::Item >
{
self . 0. get_next_buffer_size ( )
}
}
pub trait BufferProviderIterExt < ' a >
{
type Iter : iter ::Iterator < Item = NonZeroUsize > + ' a ;
fn get_all_buffer_sizes ( self ) -> Self ::Iter ;
}
pub trait BufferProviderDynIterExt < ' a >
{
fn gen_all_buffer_sizes ( self : Box < Self > ) -> Box < dyn Iterator < Item = NonZeroUsize > + ' a > ;
}
impl < ' a , T : BufferProvider + ' a > BufferProviderDynIterExt < ' a > for T
{
#[ inline ]
fn gen_all_buffer_sizes ( self : Box < Self > ) -> Box < dyn Iterator < Item = NonZeroUsize > + ' a > {
Box ::new ( BufferProviderIter ( * self ) )
}
}
impl < ' a , T : BufferProvider + ' a > BufferProviderIterExt < ' a > for T
{
type Iter = BufferProviderIter < T > ;
#[ inline(always) ]
fn get_all_buffer_sizes ( self ) -> Self ::Iter {
BufferProviderIter ( self )
}
}
impl BufferProvider for usize
{
#[ inline(always) ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
NonZeroUsize ::new ( * self )
}
}
impl BufferProvider for ( usize , usize )
{
#[ inline ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
use rand ::prelude ::* ;
NonZeroUsize ::new ( rand ::thread_rng ( ) . gen_range ( self . 0 .. self . 1 ) )
}
}
pub trait DurationProvider
{
/// Try to get the next `Duration` from this provider. If there is not one available, `None` will be returned.
///
/// # Implementations
/// * *Should* always return `Some` *at least* once with no upper bound on the number of `Some`s that can be returned.
/// * *Should* return `Some` until there are no more left (*can* be infinite.)
/// * After a `None`, there **must never** be another non-`None` value.
fn get_next_duration ( & mut self ) -> Option < Duration > ;
}
/// An iterator adaptor for a `DurationProvider`.
#[ derive(Debug, Clone) ]
pub struct DurationProviderIter < T : ? Sized > ( T ) ;
impl < T > DurationProviderIter < T >
{
/// Consume into the backing `DurationProvider`
#[ inline(always) ]
pub fn into_inner ( self ) -> T
{
self . 0
}
}
impl < T : ? Sized + DurationProvider > Iterator for DurationProviderIter < T >
{
type Item = Duration ;
#[ inline(always) ]
fn next ( & mut self ) -> Option < Self ::Item >
{
self . 0. get_next_duration ( )
}
}
pub trait DurationProviderIterExt < ' a >
{
type Iter : iter ::Iterator < Item = Duration > + ' a ;
fn get_all_durations ( self ) -> Self ::Iter ;
}
pub trait DurationProviderExt < ' a >
{
fn get_all_durations_dyn ( self : Box < Self > ) -> Box < dyn iter ::Iterator < Item = Duration > + ' a > ;
}
impl < ' a , T : DurationProvider + ' a > DurationProviderIterExt < ' a > for T
{
type Iter = DurationProviderIter < Self > ;
#[ inline(always) ]
fn get_all_durations ( self ) -> Self ::Iter {
DurationProviderIter ( self )
}
}
impl < ' a , T : ? Sized + DurationProvider + ' a > DurationProviderExt < ' a > for T
{
#[ inline ]
fn get_all_durations_dyn ( self : Box < Self > ) -> Box < dyn iter ::Iterator < Item = Duration > + ' a >
{
#[ derive(Debug) ]
struct Iter < T : ? Sized > ( Box < T > ) ;
impl < T : DurationProvider + ? Sized > Iterator for Iter < T >
{
type Item = Duration ;
fn next ( & mut self ) -> Option < Self ::Item >
{
self . 0. get_next_duration ( )
}
}
Box ::new ( Iter ( self ) )
}
}
impl DurationProvider for Duration
{
#[ inline(always) ]
fn get_next_duration ( & mut self ) -> Option < Duration > {
Some ( * self )
}
}
pub trait ThrottleProvider
{
type Timer : DurationProvider ;
fn get_timeout ( & self ) -> Self ::Timer ;
}
pub trait DynThrottleProvider < ' a >
{
fn get_timeout ( & self ) -> Box < dyn DurationProvider + ' a > ;
}
impl < ' a , T : ? Sized > DynThrottleProvider < ' a > for T
where T : ThrottleProvider ,
T ::Timer : ' a
{
#[ inline(always) ]
fn get_timeout ( & self ) -> Box < dyn DurationProvider + ' a >
{
Box ::new ( ThrottleProvider ::get_timeout ( & self ) )
}
}
impl < ' a > DurationProvider for Box < dyn DurationProvider + ' a >
{
#[ inline(always) ]
fn get_next_duration ( & mut self ) -> Option < Duration > {
( * * self ) . get_next_duration ( )
}
}
impl < ' a > ThrottleProvider for Box < dyn DynThrottleProvider < ' a > + ' a >
{
type Timer = Box < dyn DurationProvider + ' a > ;
#[ inline(always) ]
fn get_timeout ( & self ) -> Self ::Timer {
DynThrottleProvider ::get_timeout ( self )
}
}
impl < ' a > BufferProvider for Box < dyn BufferProvider + ' a >
{
#[ inline(always) ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
( * * self ) . get_next_buffer_size ( )
}
}
impl < ' a , T : ? Sized > ThrottleProvider for & ' a T
where T : ThrottleProvider
{
type Timer = T ::Timer ;
#[ inline(always) ]
fn get_timeout ( & self ) -> Self ::Timer {
T ::get_timeout ( self )
}
}
impl ThrottleProvider for Duration
{
type Timer = Self ;
fn get_timeout ( & self ) -> Self ::Timer {
self . clone ( )
}
}
/// Provides a buffer size adaptor that returns a buffer size from a uniformly-distributed `BufferProvider` range each time `get_next_buffer_size()` is called.
#[ derive(Debug, Clone, PartialEq, Eq, Hash, Copy) ]
pub struct UniformBufferProvider < T : ? Sized , R : std ::ops ::RangeBounds < T > > ( R , std ::marker ::PhantomData < T > ) ;
impl < T : ? Sized , R > From < R > for UniformBufferProvider < T , R >
where T : BufferProvider ,
R : std ::ops ::RangeBounds < T >
{
#[ inline(always) ]
fn from ( from : R ) -> Self
{
Self ( from , std ::marker ::PhantomData )
}
}
impl < T : ? Sized , R : Clone > BufferProvider for UniformBufferProvider < T , R >
where T : BufferProvider + rand ::distributions ::uniform ::SampleUniform ,
R : std ::ops ::RangeBounds < T > + rand ::distributions ::uniform ::SampleRange < T > ,
//for<'r> &'r R: ,
{
#[ inline ]
fn get_next_buffer_size ( & mut self ) -> Option < NonZeroUsize > {
use rand ::prelude ::* ;
rand ::thread_rng ( ) . gen_range ( self . 0. clone ( ) ) . get_next_buffer_size ( )
}
}
/// Provides a duration adaptor that returns a `Duration` from a uniformly-distributed `T` range each time `get_next_duration()` is called.
#[ derive(Debug, Clone, PartialEq, Eq, Hash, Copy) ]
pub struct UniformDurationProvider < T : ? Sized , R : std ::ops ::RangeBounds < T > > ( R , std ::marker ::PhantomData < T > ) ;
impl < T : ? Sized , R > From < R > for UniformDurationProvider < T , R >
where T : DurationProvider ,
R : std ::ops ::RangeBounds < T >
{
#[ inline(always) ]
fn from ( from : R ) -> Self
{
Self ( from , std ::marker ::PhantomData )
}
}
impl < T : ? Sized , R : Clone > DurationProvider for UniformDurationProvider < T , R >
where T : DurationProvider + rand ::distributions ::uniform ::SampleUniform ,
R : std ::ops ::RangeBounds < T > + rand ::distributions ::uniform ::SampleRange < T > ,
//for<'r> &'r R: rand::distributions::uniform::SampleRange<T>
{
#[ inline ]
fn get_next_duration ( & mut self ) -> Option < Duration > {
use rand ::prelude ::* ;
rand ::thread_rng ( ) . gen_range ( self . 0. clone ( ) ) . get_next_duration ( )
}
}
/// Provides a throttle adaptor that returns a uniformly-distributed `T` each time `get_timeout()` is called.
#[ derive(Debug, Clone, PartialEq, Eq, Hash) ]
pub struct UniformThrottleProvider < T : ? Sized , R : std ::ops ::RangeBounds < T > > ( R , std ::marker ::PhantomData < T > ) ;
/// Provides a single `DurationProvider` on each call to `get_timeout()`.
#[ derive(Debug, Clone, PartialEq, Eq, Hash) ]
pub struct SingleThrottleProvider < D > ( D ) ;
/// Always provides no timeout duration.
#[ derive(Debug, Clone, PartialEq, Eq, Hash) ]
pub struct NoThrottleProvider ;
/// Never provides a timeout duration
#[ derive(Debug, Clone, PartialEq, Eq, Hash) ]
pub struct NoDurationProvider ;
impl DurationProvider for NoDurationProvider
{
#[ inline(always) ]
fn get_next_duration ( & mut self ) -> Option < Duration > {
None
}
}
impl ThrottleProvider for NoThrottleProvider
{
type Timer = NoDurationProvider ;
#[ inline(always) ]
fn get_timeout ( & self ) -> Self ::Timer {
NoDurationProvider
}
}
impl < D : Clone + DurationProvider > ThrottleProvider for SingleThrottleProvider < D >
{
type Timer = D ;
#[ inline(always) ]
fn get_timeout ( & self ) -> Self ::Timer {
self . 0. clone ( )
}
}
impl From < Duration > for SingleThrottleProvider < Duration >
{
#[ inline(always) ]
fn from ( from : Duration ) -> Self
{
Self ( from )
}
}
impl < T : ? Sized , R > From < R > for UniformThrottleProvider < T , R >
where T : DurationProvider ,
R : std ::ops ::RangeBounds < T >
{
#[ inline(always) ]
fn from ( from : R ) -> Self
{
Self ( from , std ::marker ::PhantomData )
}
}
impl < T , R : Clone > ThrottleProvider for UniformThrottleProvider < T , R >
where T : DurationProvider + rand ::distributions ::uniform ::SampleUniform ,
R : std ::ops ::RangeBounds < T > + rand ::distributions ::uniform ::SampleRange < T > ,
//for <'r> &'r R: rand::distributions::uniform::SampleRange<T>,
{
type Timer = T ;
#[ inline ]
fn get_timeout ( & self ) -> Self ::Timer {
use rand ::prelude ::* ;
rand ::thread_rng ( ) . gen_range ( self . 0. clone ( ) )
}
}
pub mod prelude
{
pub use super ::{
ThrottleProvider ,
DynThrottleProvider ,
Duration ,
DurationProvider ,
BufferProvider ,
DurationProviderExt as _ ,
DurationProviderIterExt as _ ,
BufferProviderIterExt as _ ,
BufferProviderDynIterExt as _ ,
DurationProviderIter ,
BufferProviderIter ,
UniformDurationProvider ,
UniformThrottleProvider ,
UniformBufferProvider ,
SingleThrottleProvider ,
DefaultBufferSize ,
NoThrottleProvider ,
NoDurationProvider ,
NoBufferProvider ,
} ;
}