use std::time::Duration;
use std::time::Instant;
use crate::types::Request;
#[derive(Debug, Clone, Copy)]
pub struct GrpcDeadline(pub Instant);
pub fn parse_grpc_timeout(value: &str) -> Option<Duration> {
let value = value.trim();
if value.is_empty() {
return None;
}
let (num, unit) = value.split_at(value.len() - 1);
let num: u64 = num.parse().ok()?;
let dur = match unit {
"n" => Duration::from_nanos(num),
"u" => Duration::from_micros(num),
"m" => Duration::from_millis(num),
"S" => Duration::from_secs(num),
"M" => Duration::from_secs(num.checked_mul(60)?),
"H" => Duration::from_secs(num.checked_mul(3600)?),
_ => return None,
};
Some(dur)
}
pub fn read_grpc_deadline(req: &mut Request) -> Option<GrpcDeadline> {
let raw = req
.headers()
.get("grpc-timeout")
.and_then(|v| v.to_str().ok())?;
let dur = parse_grpc_timeout(raw)?;
let deadline = GrpcDeadline(Instant::now().checked_add(dur)?);
req.extensions_mut().insert(deadline);
Some(deadline)
}