use crate::{http, response::Response, server::state::State};
use http::headers::{HeaderName, HeaderValues};
use routefinder::Captures;
use std::ops::{Deref, DerefMut, Index};
pub struct Request<S: State> {
pub(crate) state: S,
pub(crate) req: http::Request,
pub(crate) captures: Vec<Captures<'static, 'static>>,
}
impl<S: State> Request<S> {
pub fn state(&self) -> &S {
&self.state
}
pub fn param(&self, key: &str) -> Option<&str> {
self.captures.iter().rev().find_map(|c| c.get(key))
}
pub fn wildcard(&self) -> Option<&str> {
self.captures.iter().rev().find_map(|c| c.wildcard())
}
}
impl<S: State> Deref for Request<S> {
type Target = http::Request;
fn deref(&self) -> &Self::Target {
&self.req
}
}
impl<S: State> DerefMut for Request<S> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.req
}
}
impl<S: State> AsRef<http::Request> for Request<S> {
fn as_ref(&self) -> &http::Request {
&self.req
}
}
impl<S: State> AsMut<http::Request> for Request<S> {
fn as_mut(&mut self) -> &mut http::Request {
&mut self.req
}
}
impl<S: State> AsRef<http::Headers> for Request<S> {
fn as_ref(&self) -> &http::Headers {
self.req.as_ref()
}
}
impl<S: State> AsMut<http::Headers> for Request<S> {
fn as_mut(&mut self) -> &mut http::Headers {
self.req.as_mut()
}
}
impl<S: State> From<Request<S>> for http::Request {
fn from(request: Request<S>) -> http::Request {
request.req
}
}
impl<S: State + Default> From<http_types::Request> for Request<S> {
fn from(req: http_types::Request) -> Request<S> {
Request {
state: S::default(),
req,
captures: vec![],
}
}
}
impl<S: State> From<Request<S>> for Response {
fn from(mut request: Request<S>) -> Response {
let mut res = Response::new(http::StatusCode::Ok);
res.set_body(request.take_body());
res
}
}
impl<S: State> IntoIterator for Request<S> {
type Item = (HeaderName, HeaderValues);
type IntoIter = http_types::headers::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.req.into_iter()
}
}
impl<'a, S: State> IntoIterator for &'a Request<S> {
type Item = (&'a HeaderName, &'a HeaderValues);
type IntoIter = http_types::headers::Iter<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.req.iter()
}
}
impl<'a, S: State> IntoIterator for &'a mut Request<S> {
type Item = (&'a HeaderName, &'a mut HeaderValues);
type IntoIter = http_types::headers::IterMut<'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.req.iter_mut()
}
}
impl<S: State> Index<&str> for Request<S> {
type Output = HeaderValues;
#[inline]
fn index(&self, index: &str) -> &Self::Output {
&self.req[index]
}
}