1#![warn(missing_docs)]
4#![forbid(unsafe_code)]
5
6pub use ureq;
7
8use pretend::client::{BlockingClient, Bytes, Method};
9use pretend::http::header::HeaderName;
10use pretend::http::HeaderValue;
11use pretend::{Error, HeaderMap, Response as PResponse, Result, StatusCode, Url};
12use std::convert::TryFrom;
13use std::io::Read;
14use ureq::Agent;
15
16pub struct Client {
18 agent: Agent,
19}
20
21impl Client {
22 pub fn new(agent: Agent) -> Self {
27 Client { agent }
28 }
29}
30
31impl BlockingClient for Client {
32 fn execute(
33 &self,
34 method: Method,
35 url: Url,
36 headers: HeaderMap,
37 body: Option<Bytes>,
38 ) -> Result<PResponse<Bytes>> {
39 let mut request = self.agent.request_url(method.as_str(), &url);
40
41 for (name, value) in headers.iter() {
42 let value = value.to_str();
43 let value = value.map_err(|err| Error::Request(Box::new(err)))?;
44 request = request.set(name.as_str(), value);
45 }
46
47 let response = if let Some(body) = body {
48 request.send_bytes(&body)
49 } else {
50 request.call()
51 };
52
53 let response = response.map_err(|err| Error::Response(Box::new(err)))?;
54
55 let status = StatusCode::from_u16(response.status());
56 let status = status.map_err(|err| Error::Response(Box::new(err)))?;
57
58 let mut headers = HeaderMap::new();
59 for name in response.headers_names() {
60 let values = response.all(&name);
61
62 let name = HeaderName::try_from(&name);
63 let name = name.map_err(|err| Error::Response(Box::new(err)))?;
64
65 for value in values {
66 let value = HeaderValue::try_from(value);
67 let value = value.map_err(|err| Error::Response(Box::new(err)))?;
68
69 headers.append(&name, value);
70 }
71 }
72
73 let mut body = Vec::new();
74 let mut reader = response.into_reader();
75 reader
76 .read_to_end(&mut body)
77 .map_err(|err| Error::Response(Box::new(err)))?;
78
79 Ok(PResponse::new(status, headers, Bytes::from(body)))
80 }
81}