1use crate::human::{parse_bytes, parse_duration};
4use crate::route_value::RouteValue;
5use std::borrow::Cow;
6use std::time::{Duration, Instant};
7
8#[derive(Debug, Clone, Copy)]
10pub struct MaxBody(pub usize);
11
12impl MaxBody {
13 pub fn bytes(n: usize) -> Self {
14 Self(n)
15 }
16
17 pub fn kib(n: usize) -> Self {
18 Self(n.saturating_mul(1024))
19 }
20
21 pub fn mib(n: usize) -> Self {
22 Self(n.saturating_mul(1024 * 1024))
23 }
24
25 pub fn parse(s: &str) -> Result<Self, String> {
26 Ok(Self(parse_bytes(s)?))
27 }
28}
29
30impl RouteValue for MaxBody {
31 fn label(&self) -> Cow<'static, str> {
32 Cow::Owned(format!("MaxBody({} bytes)", self.0))
33 }
34}
35
36#[derive(Debug, Clone, Copy)]
38pub struct RequestTimeout(pub Duration);
39
40impl RequestTimeout {
41 pub fn from_secs(secs: u64) -> Self {
42 Self(Duration::from_secs(secs))
43 }
44
45 pub fn parse(s: &str) -> Result<Self, String> {
46 Ok(Self(parse_duration(s)?))
47 }
48}
49
50impl RouteValue for RequestTimeout {
51 fn label(&self) -> Cow<'static, str> {
52 Cow::Owned(format!("RequestTimeout({:?})", self.0))
53 }
54}
55
56#[derive(Debug, Clone, Copy)]
60pub struct Deadline(pub Instant);
61
62impl Deadline {
63 pub fn at(instant: Instant) -> Self {
64 Self(instant)
65 }
66
67 pub fn after(dur: Duration) -> Self {
68 Self(Instant::now() + dur)
69 }
70
71 pub fn remaining(&self) -> Duration {
73 self.0.saturating_duration_since(Instant::now())
74 }
75}
76
77pub fn tighten_deadline(req: &mut crate::Request, until: Instant) {
79 match req.get::<Deadline>() {
80 Some(d) if d.0 <= until => {}
81 _ => req.set(Deadline(until)),
82 }
83}