Open mmstick opened 5 years ago
Sounds like a good idea to me!
This is a great idea.
I just implemented this for myself:
use ::std::time::Duration;
pub enum RetryResult<T, E> {
Ok(T),
Retry(E),
Err(E),
}
impl<T, E> From<Result<T, E>> for RetryResult<T, E> {
fn from(r : Result<T, E>) -> Self {
match r {
Ok(v) => RetryResult::Ok(v),
Err(e) => RetryResult::Retry(e),
}
}
}
pub struct Retry {
attempts: Option<u64>,
interval: Duration,
}
impl Default for Retry {
fn default() -> Self {
Retry {
attempts: None,
interval: Duration::from_millis(1000),
}
}
}
impl Retry {
pub fn attempts(mut self, attempts: u64) -> Self {
self.attempts = Some(attempts);
self
}
pub fn interval(mut self, interval: u64) -> Self {
self.interval = Duration::from_millis(interval);
self
}
pub fn retry_until_ok<F, T, E, R>(&self, mut func: F) -> Result<T, E>
where F: FnMut() -> R,
R : Into<RetryResult<T, E>>
{
let mut attempt = 0;
loop {
match func().into() {
RetryResult::Ok(value) => return Ok(value),
RetryResult::Err(why) => return Err(why),
RetryResult::Retry(why) => {
if Some(attempt) == self.attempts {
return Err(why);
} else {
attempt += 1;
::std::thread::sleep(self.interval);
}
}
}
}
}
}
Looking for a solution like this: