use http::{HeaderMap, Method, Uri, Version};
use http_service::Body;
use route_recognizer::Params;
use std::{str::FromStr, sync::Arc};
#[derive(Debug)]
pub struct Context<State> {
state: Arc<State>,
request: http_service::Request,
route_params: Params,
}
impl<State> Context<State> {
pub(crate) fn new(
state: Arc<State>,
request: http::Request<Body>,
route_params: Params,
) -> Context<State> {
Context {
state,
request,
route_params,
}
}
pub fn method(&self) -> &Method {
self.request.method()
}
pub fn uri(&self) -> &Uri {
self.request.uri()
}
pub fn version(&self) -> Version {
self.request.version()
}
pub fn headers(&self) -> &HeaderMap {
self.request.headers()
}
pub fn request(&self) -> &http_service::Request {
&self.request
}
pub fn state(&self) -> &State {
&self.state
}
pub fn param<T: FromStr>(&self, key: &str) -> Result<T, T::Err> {
self.route_params.find(key).unwrap().parse()
}
pub async fn body_bytes(&mut self) -> std::io::Result<Vec<u8>> {
self.take_body().into_vec().await
}
pub async fn body_string(&mut self) -> std::io::Result<String> {
let body_bytes = self.body_bytes().await?;
Ok(String::from_utf8(body_bytes).map_err(|_| std::io::ErrorKind::InvalidData)?)
}
pub async fn body_json<T: serde::de::DeserializeOwned>(&mut self) -> std::io::Result<T> {
let body_bytes = self.body_bytes().await?;
Ok(serde_json::from_slice(&body_bytes).map_err(|_| std::io::ErrorKind::InvalidData)?)
}
pub fn take_body(&mut self) -> Body {
std::mem::replace(self.request.body_mut(), Body::empty())
}
pub fn extensions(&self) -> &http::Extensions {
self.request.extensions()
}
pub fn extensions_mut(&mut self) -> &mut http::Extensions {
self.request.extensions_mut()
}
}