//! 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 > ) ;
#[ cfg(feature= " none " ) ]
const _ :( ) = {
use rand ::distributions ::uniform ::{
self ,
UniformSampler ,
SampleUniform ,
SampleRange ,
Uniform ,
} ;
use std ::{
ops ::{
RangeBounds ,
Bound ,
} ,
} ;
#[ derive(Debug) ]
struct UniformDurationProviderSampler < T :? Sized , R : std ::ops ::RangeBounds < T > > ( UniformDurationProvider < T , R > ) ;
impl < T : ? Sized , R : RangeBounds < T > > UniformSampler for UniformDurationProviderSampler < T , R >
where R : SampleRange < T > ,
T : SampleUniform ,
{
type X = UniformDurationProvider < T , R > ;
fn new_inclusive < B1 , B2 > ( low : B1 , high : B2 ) -> Self
where
B1 : uniform ::SampleBorrow < Self ::X > + Sized ,
B2 : uniform ::SampleBorrow < Self ::X > + Sized {
Self ( < Self ::X as UniformSampler > ::X ::new_inclusive ( low , high ) )
}
fn sample < Rng : rand ::Rng + ? Sized > ( & self , rng : & mut Rng ) -> Self ::X {
//use rand::prelude::*;
//UniformDurationProvider(self.0.sample(rng))
todo! ( )
}
fn new < B1 , B2 > ( low : B1 , high : B2 ) -> Self
where
B1 : uniform ::SampleBorrow < Self ::X > + Sized ,
B2 : uniform ::SampleBorrow < Self ::X > + Sized {
< Self ::X as UniformSampler > ::new ( low , high )
}
}
} ;
#[ cfg(feature= " FUCK THIS " ) ]
const _ :( ) = {
use rand ::distributions ::uniform ::{
self ,
UniformSampler ,
SampleUniform ,
SampleRange ,
Uniform ,
} ;
use std ::{
ops ::{
RangeBounds ,
Bound ,
} ,
marker ::PhantomData
} ;
use crate ::ext ::* ;
#[ derive(Debug, Clone, Copy) ]
struct UDPSampler < R > ( uniform ::UniformDuration , PhantomData < R > ) ;
impl < D > UniformSampler for UDPSampler < D >
where D : RangeBounds < Duration >
{
type X = UniformDurationProvider < Duration , D > ;
fn new_inclusive < B1 , B2 > ( low : B1 , high : B2 ) -> Self
where
B1 : uniform ::SampleBorrow < Self ::X > + Sized ,
B2 : uniform ::SampleBorrow < Self ::X > + Sized
{
Self ( uniform ::UniformDuration ::new_inclusive ( low . borrow ( ) . 0. start_bound ( ) , high . borrow ( ) . 0. end_bound ( ) ) , PhantomData )
}
fn sample < R : rand ::Rng + ? Sized > ( & self , rng : & mut R ) -> Self ::X {
todo! ( )
}
fn new < B1 , B2 > ( low : B1 , high : B2 ) -> Self
where
B1 : uniform ::SampleBorrow < Self ::X > + Sized ,
B2 : uniform ::SampleBorrow < Self ::X > + Sized
{
Self ( uniform ::UniformDuration ::new ( low , high ) , PhantomData )
}
}
impl < R > SampleUniform for UniformDurationProvider < Duration , R >
where R : RangeBounds < Duration > + SampleRange < Duration >
{
type Sampler = UDPSampler < R > ;
}
} ;
impl < T , R > rand ::distributions ::uniform ::SampleRange < T > for UniformDurationProvider < T , R >
where R : std ::ops ::RangeBounds < T > + rand ::distributions ::uniform ::SampleRange < T > ,
T : rand ::distributions ::uniform ::SampleUniform
{
#[ inline(always) ]
fn sample_single < Rng : rand ::RngCore + ? Sized > ( self , rng : & mut Rng ) -> T {
self . 0. sample_single ( rng )
}
#[ inline ]
fn is_empty ( & self ) -> bool {
use super ::ext ::* ;
self . 0. start_bound ( ) . map_impl ( into_addr ) = = self . 0. end_bound ( ) . map_impl ( into_addr )
}
}
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 : ? Sized > ( D ) ;
impl < D : DurationProvider > From < D > for SingleThrottleProvider < D >
{
#[ inline(always) ]
fn from ( from : D ) -> Self
{
Self ( from )
}
}
/// 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 )
}
} * /
//TODO: Split this into multiple: From<Range/Inclusive>: same.
// And From<x..>,From<..{,=}x>: x..BUFFER_MAX_LEN, 0..{,=}x
// (seperate impls needed for type signature. which is annoying...)
//
// XXX: Alternatively, we could add `new_from_range<R2>(range: R2)` methods for UniformThrottleProvider<_, R> where R determines which we use. This is probably the better way of doing it.
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 ,
} ;
}