fire_http_representation/request/
builder.rs1use super::Request;
2use crate::body::Body;
3use crate::header::{
4 values::IntoHeaderName, ContentType, HeaderValue, HeaderValues, Method,
5 RequestHeader, Uri, CONTENT_LENGTH, CONTENT_TYPE,
6};
7
8use std::fmt;
9use std::net::SocketAddr;
10
11#[derive(Debug)]
15pub struct RequestBuilder {
16 header: RequestHeader,
17 body: Body,
18}
19
20impl RequestBuilder {
21 pub fn new(uri: Uri) -> Self {
23 Self {
24 header: RequestHeader {
25 address: ([127, 0, 0, 1], 0).into(),
26 method: Method::GET,
27 uri,
28 values: HeaderValues::new(),
29 },
30 body: Body::new(),
31 }
32 }
33
34 pub fn address(mut self, addr: impl Into<SocketAddr>) -> Self {
36 self.header.address = addr.into();
37 self
38 }
39
40 pub fn method(mut self, method: Method) -> Self {
42 self.header.method = method;
43 self
44 }
45
46 pub fn content_type(self, content_type: impl Into<ContentType>) -> Self {
48 self.header(CONTENT_TYPE, content_type.into())
49 }
50
51 pub fn header<K, V>(mut self, key: K, val: V) -> Self
60 where
61 K: IntoHeaderName,
62 V: TryInto<HeaderValue>,
63 V::Error: fmt::Debug,
64 {
65 self.values_mut().insert(key, val);
66 self
67 }
68
69 pub fn values_mut(&mut self) -> &mut HeaderValues {
71 &mut self.header.values
72 }
73
74 pub fn body(mut self, body: impl Into<Body>) -> Self {
76 self.body = body.into();
77 self
78 }
79
80 #[cfg(feature = "json")]
82 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
83 pub fn serialize<S: ?Sized>(
84 self,
85 value: &S,
86 ) -> Result<Self, super::SerializeError>
87 where
88 S: serde::Serialize,
89 {
90 Ok(self.body(
91 Body::serialize(value)
92 .map_err(|e| super::SerializeError::Json(e))?,
93 ))
94 }
95
96 #[cfg(feature = "query")]
101 #[cfg_attr(docsrs, doc(cfg(feature = "query")))]
102 pub fn serialize_query<S: ?Sized>(
103 mut self,
104 value: &S,
105 ) -> Result<Self, super::SerializeError>
106 where
107 S: serde::Serialize,
108 {
109 let mut parts = self.header.uri.into_parts();
110
111 let query = serde_urlencoded::to_string(&value)
112 .map_err(|e| super::SerializeError::UrlEncoded(e))?;
113
114 parts.path_and_query = Some(
115 format!(
116 "{}?{}",
117 parts
118 .path_and_query
119 .as_ref()
120 .map(|p| p.path())
121 .unwrap_or("/"),
122 query
123 )
124 .parse()
125 .expect("serde_urlencoded should always return a valid query"),
126 );
127
128 self.header.uri = Uri::from_parts(parts).unwrap();
129
130 Ok(self)
131 }
132
133 pub fn build(mut self) -> Request {
136 if let Some(len) = self.body.len() {
139 self.values_mut().insert(CONTENT_LENGTH, len);
140 }
141
142 Request::new(self.header, self.body)
143 }
144}