use crate::strategies::RetryStrategy;
use std::error::Error;
use std::time::Duration;
#[derive(Debug)]
pub struct RetryConfig<E> {
pub max_attempts: usize,
pub delay: Duration,
pub strategy: RetryStrategy,
pub retry_condition: Option<fn(&E) -> bool>,
}
impl<E> Default for RetryConfig<E> {
fn default() -> Self {
RetryConfig {
max_attempts: 3,
delay: Duration::from_secs(2),
strategy: RetryStrategy::Linear,
retry_condition: None,
}
}
}
impl<E> RetryConfig<E> {
pub fn new(max_attempts: usize, delay: Duration, strategy: RetryStrategy) -> Self {
RetryConfig {
max_attempts,
delay,
strategy,
retry_condition: None,
}
}
pub fn with_retry_condition(mut self, retry_condition: fn(&E) -> bool) -> Self {
self.retry_condition = Some(retry_condition);
self
}
pub fn with_strategy(mut self, strategy: RetryStrategy) -> Self {
self.strategy = strategy;
self
}
}
#[derive(Debug)]
pub struct ExecConfig<T> {
pub timeout_duration: Duration,
pub fallback: Option<fn() -> Result<T, Box<dyn Error>>>,
}
impl<T> ExecConfig<T>
where
T: Clone,
{
pub fn new(timeout_duration: Duration) -> Self {
ExecConfig {
timeout_duration,
fallback: None,
}
}
pub fn with_fallback(&mut self, fallback: fn() -> Result<T, Box<dyn Error>>) {
self.fallback = Some(fallback);
}
}
#[derive(Debug, Clone, Copy)]
pub struct CircuitBreakerConfig {
pub failure_threshold: usize,
pub success_threshold: usize,
pub cooldown_period: Duration,
}
impl Default for CircuitBreakerConfig {
fn default() -> Self {
Self {
success_threshold: 2,
failure_threshold: 5,
cooldown_period: Duration::from_secs(2),
}
}
}
impl CircuitBreakerConfig {
pub fn new(
success_threshold: usize,
failure_threshold: usize,
cooldown_period: Duration,
) -> Self {
assert!(
success_threshold > 0,
"success_threshold must be greater than 0"
);
assert!(
failure_threshold > 0,
"failure_threshold must be greater than 0"
);
assert!(
cooldown_period > Duration::ZERO,
"cooldown_period must be non-zero"
);
Self {
failure_threshold,
success_threshold,
cooldown_period,
}
}
pub fn with_failure_threshold(mut self, threshold: usize) -> Self {
assert!(threshold > 0, "failure_threshold must be greater than 0");
self.failure_threshold = threshold;
self
}
pub fn with_success_threshold(mut self, threshold: usize) -> Self {
assert!(threshold > 0, "success_threshold must be greater than 0");
self.success_threshold = threshold;
self
}
pub fn with_cooldown_period(mut self, period: Duration) -> Self {
assert!(period > Duration::ZERO, "cooldown_period must be non-zero");
self.cooldown_period = period;
self
}
}