#![cfg(feature = "__rt_native__")]
use std::time::Duration;
#[derive(Clone, Copy, Debug)]
pub struct Timeout(Duration);
impl Timeout {
pub fn by(duration: Duration) -> Self {
Self(duration)
}
pub const fn by_secs(secs: u64) -> Self {
Self(Duration::from_secs(secs))
}
pub const fn by_millis(millis: u64) -> Self {
Self(Duration::from_millis(millis))
}
pub fn by_secs_f32(secs: f32) -> Self {
Self(Duration::from_secs_f32(secs))
}
pub fn by_secs_f64(secs: f64) -> Self {
Self(Duration::from_secs_f64(secs))
}
}
const _: () = {
use crate::{Fang, FangProc, Request, Response};
impl<Inner: FangProc> Fang<Inner> for Timeout {
type Proc = TimeoutProc<Inner>;
fn chain(&self, inner: Inner) -> Self::Proc {
TimeoutProc {
time: self.0,
inner,
}
}
}
pub struct TimeoutProc<Inner: FangProc> {
inner: Inner,
time: Duration,
}
impl<Inner: FangProc> FangProc for TimeoutProc<Inner> {
async fn bite<'b>(&'b self, req: &'b mut Request) -> Response {
crate::util::with_timeout(self.time, self.inner.bite(req))
.await
.unwrap_or_else(|| Response::InternalServerError().with_text("timeout"))
}
}
};
#[cfg(all(test, debug_assertions, feature = "__rt_native__", feature = "DEBUG"))]
#[test]
fn test_timeout() {
use crate::prelude::*;
use crate::testing::*;
async fn lazy_greeting(Path((name, sleep)): Path<(&str, u64)>) -> String {
crate::__rt__::sleep(Duration::from_secs(sleep)).await;
format!("Hello, {name}!")
}
let t = Ohkami::new((
Timeout::by_secs(2),
"/greet/:name/:sleep".GET(lazy_greeting),
))
.test();
crate::__rt__::testing::block_on(async {
{
let req = TestRequest::GET("/greet");
let res = t.oneshot(req).await;
assert_eq!(res.status(), Status::NotFound);
}
{
let req = TestRequest::PUT("/greet/ohkami/1");
let res = t.oneshot(req).await;
assert_eq!(res.status(), Status::NotFound);
}
{
let req = TestRequest::GET("/greet/ohkami/1");
let res = t.oneshot(req).await;
assert_eq!(res.status(), Status::OK);
assert_eq!(res.text(), Some("Hello, ohkami!"));
}
{
let req = TestRequest::GET("/greet/ohkami/3");
let res = t.oneshot(req).await;
assert_eq!(res.status(), Status::InternalServerError);
assert_eq!(res.text(), Some("timeout"));
}
});
}