http/uri/
builder.rs
1use std::convert::TryInto;
2
3use super::{Authority, Parts, PathAndQuery, Scheme};
4use crate::Uri;
5
6#[derive(Debug)]
11pub struct Builder {
12 parts: Result<Parts, crate::Error>,
13}
14
15impl Builder {
16 #[inline]
31 pub fn new() -> Builder {
32 Builder::default()
33 }
34
35 pub fn scheme<T>(self, scheme: T) -> Self
46 where
47 T: TryInto<Scheme>,
48 <T as TryInto<Scheme>>::Error: Into<crate::Error>,
49 {
50 self.map(move |mut parts| {
51 let scheme = scheme.try_into().map_err(Into::into)?;
52 parts.scheme = Some(scheme);
53 Ok(parts)
54 })
55 }
56
57 pub fn authority<T>(self, auth: T) -> Self
70 where
71 T: TryInto<Authority>,
72 <T as TryInto<Authority>>::Error: Into<crate::Error>,
73 {
74 self.map(move |mut parts| {
75 let auth = auth.try_into().map_err(Into::into)?;
76 parts.authority = Some(auth);
77 Ok(parts)
78 })
79 }
80
81 pub fn path_and_query<T>(self, p_and_q: T) -> Self
94 where
95 T: TryInto<PathAndQuery>,
96 <T as TryInto<PathAndQuery>>::Error: Into<crate::Error>,
97 {
98 self.map(move |mut parts| {
99 let p_and_q = p_and_q.try_into().map_err(Into::into)?;
100 parts.path_and_query = Some(p_and_q);
101 Ok(parts)
102 })
103 }
104
105 pub fn build(self) -> Result<Uri, crate::Error> {
130 let parts = self.parts?;
131 Uri::from_parts(parts).map_err(Into::into)
132 }
133
134 fn map<F>(self, func: F) -> Self
137 where
138 F: FnOnce(Parts) -> Result<Parts, crate::Error>,
139 {
140 Builder {
141 parts: self.parts.and_then(func),
142 }
143 }
144}
145
146impl Default for Builder {
147 #[inline]
148 fn default() -> Builder {
149 Builder {
150 parts: Ok(Parts::default()),
151 }
152 }
153}
154
155impl From<Uri> for Builder {
156 fn from(uri: Uri) -> Self {
157 Self {
158 parts: Ok(uri.into_parts()),
159 }
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn build_from_str() {
169 let uri = Builder::new()
170 .scheme(Scheme::HTTP)
171 .authority("hyper.rs")
172 .path_and_query("/foo?a=1")
173 .build()
174 .unwrap();
175 assert_eq!(uri.scheme_str(), Some("http"));
176 assert_eq!(uri.authority().unwrap().host(), "hyper.rs");
177 assert_eq!(uri.path(), "/foo");
178 assert_eq!(uri.query(), Some("a=1"));
179 }
180
181 #[test]
182 fn build_from_string() {
183 for i in 1..10 {
184 let uri = Builder::new()
185 .path_and_query(format!("/foo?a={}", i))
186 .build()
187 .unwrap();
188 let expected_query = format!("a={}", i);
189 assert_eq!(uri.path(), "/foo");
190 assert_eq!(uri.query(), Some(expected_query.as_str()));
191 }
192 }
193
194 #[test]
195 fn build_from_string_ref() {
196 for i in 1..10 {
197 let p_a_q = format!("/foo?a={}", i);
198 let uri = Builder::new().path_and_query(&p_a_q).build().unwrap();
199 let expected_query = format!("a={}", i);
200 assert_eq!(uri.path(), "/foo");
201 assert_eq!(uri.query(), Some(expected_query.as_str()));
202 }
203 }
204
205 #[test]
206 fn build_from_uri() {
207 let original_uri = Uri::default();
208 let uri = Builder::from(original_uri.clone()).build().unwrap();
209 assert_eq!(original_uri, uri);
210 }
211}