1use crate::{Authority, Fields, Method, Path, Protocol, Scheme, Version, body::EmptyBody};
5use std::ops::{Deref, DerefMut};
6
7#[derive(Clone, Debug)]
11pub struct RequestMetadata {
12 pub method: Method,
13 pub scheme: Option<Scheme>,
14 pub authority: Option<Authority>,
15 pub path: Option<Path>,
18 pub version: Option<Version>,
19 pub fields: Fields,
20 pub content_length: Option<u64>,
23 pub persistent: Option<bool>,
26 pub protocol: Option<Protocol>,
27}
28
29impl RequestMetadata {
30 pub fn new(method: Method) -> Self {
31 Self {
32 method,
33 scheme: None,
34 authority: None,
35 path: None,
36 version: None,
37 fields: Fields::new(),
38 content_length: None,
39 persistent: None,
40 protocol: None,
41 }
42 }
43
44 pub fn declared_length(&self, body: Option<u64>) -> Option<u64> {
46 self.content_length
47 .filter(|&declared| body.is_none_or(|body| body == declared))
48 }
49}
50
51#[derive(Clone, Debug)]
54pub struct Request<B = EmptyBody> {
55 pub metadata: RequestMetadata,
56 pub body: B,
57}
58
59impl<B> Request<B> {
60 pub fn new(method: Method, path: impl Into<Path>, body: B) -> Self {
61 let mut metadata = RequestMetadata::new(method);
62 metadata.path = Some(path.into());
63 Self { metadata, body }
64 }
65
66 pub fn from_parts(metadata: RequestMetadata, body: B) -> Self {
67 Self { metadata, body }
68 }
69 pub fn into_parts(self) -> (RequestMetadata, B) {
70 (self.metadata, self.body)
71 }
72 pub fn map_body<T>(self, map: impl FnOnce(B) -> T) -> Request<T> {
74 Request {
75 metadata: self.metadata,
76 body: map(self.body),
77 }
78 }
79 pub fn with_body<T>(self, body: T) -> Request<T> {
82 self.map_body(|_| body)
83 }
84 pub fn is_head(&self) -> bool {
85 self.method == Method::HEAD
86 }
87 pub fn is_connect(&self) -> bool {
88 self.method == Method::CONNECT
89 }
90}
91
92impl Request<EmptyBody> {
93 pub fn get(path: impl Into<Path>) -> Self {
94 Self::new(Method::GET, path, EmptyBody)
95 }
96}
97
98impl<B> Deref for Request<B> {
99 type Target = RequestMetadata;
100 fn deref(&self) -> &Self::Target {
101 &self.metadata
102 }
103}
104impl<B> DerefMut for Request<B> {
105 fn deref_mut(&mut self) -> &mut Self::Target {
106 &mut self.metadata
107 }
108}
109
110impl<B: crate::body::ReadableBody> Request<B> {
111 pub fn length(&self) -> Option<u64> {
113 let body = self.body.length();
114 body.or(self.metadata.declared_length(body))
115 }
116
117 pub async fn read(
120 &mut self,
121 cancellation: &base_scheduler::Cancellation,
122 ) -> Result<crate::body::BodyFrame<B::Data>, B::Error> {
123 self.body.read(cancellation).await
124 }
125}