use std::time::Duration;
use async_trait::async_trait;
use http::Extensions;
use reqwest::{Request, Response};
use super::{Error, Middleware, Next, Result};
use crate::error::FetchError;
#[derive(Debug, Clone)]
pub struct TimeoutMiddleware {
timeout: Duration,
}
impl TimeoutMiddleware {
pub fn new(timeout: Duration) -> Self {
Self { timeout }
}
}
#[async_trait]
impl Middleware for TimeoutMiddleware {
async fn handle(
&self,
req: Request,
extensions: &mut Extensions,
next: Next<'_>,
) -> Result<Response> {
match tokio::time::timeout(self.timeout, next.run(req, extensions)).await {
Ok(result) => result,
Err(_elapsed) => Err(Error::Middleware(
FetchError::Timeout(self.timeout).into(),
)),
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used, clippy::expect_used)] use super::*;
#[test]
fn configured_duration_is_stored() {
let mw = TimeoutMiddleware::new(Duration::from_millis(250));
assert_eq!(mw.timeout, Duration::from_millis(250));
}
}