greyhound 0.0.1

al3x's personal backend framework
Documentation
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]
	}
}