pretend_ureq/
lib.rs

1//! `ureq` based `pretend` client
2
3#![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
16/// `ureq` based `pretend` client
17pub struct Client {
18    agent: Agent,
19}
20
21impl Client {
22    /// Constructor with custom agent
23    ///
24    /// This constructor creates a client implementation
25    /// for `pretend` wrapping the supplied `ureq` agent.
26    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}