use crate::core::EaseOffCore;
use crate::EaseOff;
use std::num::Saturating;
use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct Options {
pub(crate) multiplier: f32,
pub(crate) jitter: f32,
pub(crate) initial_jitter: f32,
pub(crate) initial_delay: Duration,
pub(crate) max_delay: Duration,
}
impl Options {
pub const DEFAULT: Options = Options {
multiplier: 2.0,
jitter: 0.25,
initial_jitter: 0.0,
initial_delay: Duration::from_millis(150),
max_delay: Duration::from_secs(60), };
#[inline(always)]
pub const fn new() -> Self {
Self::DEFAULT
}
#[inline(always)]
pub const fn multiplier(self, multiplier: f32) -> Self {
Self { multiplier, ..self }
}
#[inline(always)]
pub const fn get_multiplier(&self) -> f32 {
self.multiplier
}
#[inline(always)]
pub const fn jitter(self, jitter: f32) -> Self {
Self { jitter, ..self }
}
#[inline(always)]
pub const fn get_jitter(&self) -> f32 {
self.jitter
}
#[inline(always)]
pub const fn initial_jitter(self, initial_jitter: f32) -> Self {
Self {
initial_jitter,
..self
}
}
#[inline(always)]
pub const fn get_initial_jitter(&self) -> f32 {
self.initial_jitter
}
#[inline(always)]
pub const fn initial_delay(self, initial_delay: Duration) -> Self {
Self {
initial_delay,
..self
}
}
#[inline(always)]
pub const fn get_initial_delay(&self) -> Duration {
self.initial_delay
}
#[inline(always)]
pub const fn max_delay(self, max_delay: Duration) -> Self {
Self { max_delay, ..self }
}
#[inline(always)]
pub const fn get_max_delay(&self) -> Duration {
self.max_delay
}
#[inline(always)]
pub const fn into_core(self) -> EaseOffCore {
EaseOffCore::new(self)
}
}
impl Options {
pub fn start_unlimited<E>(&self) -> EaseOff<E> {
self.start(Instant::now(), None)
}
pub fn start_timeout<E>(&self, timeout: Duration) -> EaseOff<E> {
let started_at = Instant::now();
self.start(started_at, started_at.checked_add(timeout))
}
pub fn start_timeout_opt<E>(&self, timeout: Option<Duration>) -> EaseOff<E> {
let started_at = Instant::now();
self.start(
started_at,
timeout.and_then(|timeout| started_at.checked_add(timeout)),
)
}
pub fn start_deadline<E>(&self, deadline: Instant) -> EaseOff<E> {
self.start(Instant::now(), Some(deadline))
}
pub fn start_deadline_opt<E>(&self, deadline: Option<Instant>) -> EaseOff<E> {
self.start(Instant::now(), deadline)
}
fn start<E>(&self, started_at: Instant, deadline: Option<Instant>) -> EaseOff<E> {
EaseOff {
core: EaseOffCore::new(self.clone()),
started_at,
deadline,
num_attempts: Saturating(0),
last_error: None,
next_retry_at: None,
}
}
}
impl Default for Options {
#[inline(always)]
fn default() -> Self {
Self::DEFAULT
}
}