use std::{fmt::Debug};
use hyper::{Version, Body, Method, header::{HeaderName, HeaderValue}, Uri};
use routefinder::Captures;
use typemap::Key;
#[derive(Debug)]
pub struct Context {
pub req: crate::Request<Body>,
ctx: typemap::ShareDebugMap,
pub params: Vec<Captures<'static, 'static>>,
}
impl Context {
pub(crate) fn new(
req: crate::Request<Body>,
params: Vec<Captures<'static, 'static>>,
) -> Self {
Self {
req,
ctx: typemap::ShareDebugMap::custom(),
params,
}
}
#[must_use]
pub fn method(&self) -> &Method {
self.req.method()
}
#[must_use]
pub fn uri(&self) -> &Uri {
self.req.uri()
}
#[must_use]
pub fn version(&self) -> Version {
self.req.version()
}
#[must_use]
pub fn host(&self) -> Option<&str> {
self.req.uri().host()
}
#[must_use]
pub fn header(
&self,
key: impl Into<HeaderName>,
) -> Option<&HeaderValue> {
self.req.headers().get(key.into())
}
pub fn header_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValue> {
self.req.headers_mut().get_mut(name.into())
}
pub fn insert_header(
&mut self,
name: impl Into<HeaderName>,
value: impl Into<HeaderValue>,
) -> Option<HeaderValue> {
self.req.headers_mut().insert(name.into(), value.into())
}
pub fn remove_header(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValue> {
self.req.headers_mut().remove(name.into())
}
#[must_use]
pub fn get<T: Key<Value = T> + Debug + Send + Sync>(&self) -> Option<&T> {
self.ctx.get::<T>()
}
#[must_use]
pub fn get_mut<T: Key<Value = T> + Debug + Send + Sync>(&mut self) -> Option<&mut T> {
self.ctx.get_mut::<T>()
}
pub fn set<T: Key<Value = T> + Debug + Send + Sync>(&mut self, val: T) -> Option<T> {
self.ctx.insert::<T>(val)
}
pub fn param(&self, key: &str) -> crate::Result<&str> {
self.params
.iter()
.rev()
.find_map(|captures| captures.get(key))
.ok_or_else(|| anyhow::anyhow!("Param \"{}\" not found", key.to_string()).into())
}
pub fn wildcard(&self) -> Option<&str> {
self.params
.iter()
.rev()
.find_map(|captures| captures.wildcard())
}
}
impl AsRef<crate::Request<Body>> for Context {
fn as_ref(&self) -> &crate::Request<Body> {
&self.req
}
}
impl AsMut<crate::Request<Body>> for Context {
fn as_mut(&mut self) -> &mut crate::Request<Body> {
&mut self.req
}
}