use crate::{Authority, Fields, Method, Path, Protocol, Scheme, Version, body::EmptyBody};
use std::ops::{Deref, DerefMut};
#[derive(Clone, Debug)]
pub struct RequestMetadata {
pub method: Method,
pub scheme: Option<Scheme>,
pub authority: Option<Authority>,
pub path: Option<Path>,
pub version: Option<Version>,
pub fields: Fields,
pub content_length: Option<u64>,
pub persistent: Option<bool>,
pub protocol: Option<Protocol>,
}
impl RequestMetadata {
pub fn new(method: Method) -> Self {
Self {
method,
scheme: None,
authority: None,
path: None,
version: None,
fields: Fields::new(),
content_length: None,
persistent: None,
protocol: None,
}
}
}
#[derive(Clone, Debug)]
pub struct Request<B = EmptyBody> {
pub metadata: RequestMetadata,
pub body: B,
}
impl<B> Request<B> {
pub fn new(method: Method, path: impl Into<Path>, body: B) -> Self {
let mut metadata = RequestMetadata::new(method);
metadata.path = Some(path.into());
Self { metadata, body }
}
pub fn from_parts(metadata: RequestMetadata, body: B) -> Self {
Self { metadata, body }
}
pub fn into_parts(self) -> (RequestMetadata, B) {
(self.metadata, self.body)
}
pub fn map_body<T>(self, map: impl FnOnce(B) -> T) -> Request<T> {
Request {
metadata: self.metadata,
body: map(self.body),
}
}
pub fn with_body<T>(self, body: T) -> Request<T> {
self.map_body(|_| body)
}
pub fn is_head(&self) -> bool {
self.method == Method::HEAD
}
pub fn is_connect(&self) -> bool {
self.method == Method::CONNECT
}
}
impl Request<EmptyBody> {
pub fn get(path: impl Into<Path>) -> Self {
Self::new(Method::GET, path, EmptyBody)
}
}
impl<B> Deref for Request<B> {
type Target = RequestMetadata;
fn deref(&self) -> &Self::Target {
&self.metadata
}
}
impl<B> DerefMut for Request<B> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.metadata
}
}
impl<B: crate::body::ReadableBody> Request<B> {
pub async fn read(
&mut self,
cancellation: &base_scheduler::Cancellation,
) -> Result<crate::body::BodyFrame<B::Data>, B::Error> {
self.body.read(cancellation).await
}
}