cargo_api/client/
reqwest.rs1use crate::api::ApiError::HttpRequest;
2use crate::api::{ApiError, Client};
3use bytes::Bytes;
4use http::request::Builder;
5use reqwest::ResponseBuilderExt;
6use std::borrow::Cow;
7use url::Url;
8
9const CRATES_API: &'static str = "https://crates.io/api/";
10
11pub struct ReqwestClient {
12 client: reqwest::blocking::Client,
13 url: Url,
16}
17
18impl ReqwestClient {
19 pub fn new(user_agent: &str) -> Self {
20 Self {
21 client: reqwest::blocking::ClientBuilder::default()
22 .user_agent(user_agent)
23 .build()
24 .unwrap(),
25 url: Url::parse(CRATES_API).unwrap(),
26 }
27 }
28
29 fn send_request(
30 &self,
31 request: http::Request<Vec<u8>>,
32 ) -> Result<http::Response<Bytes>, Error> {
33 let req = request.try_into()?;
35
36 let res = self.client.execute(req)?;
38
39 let http_res = into_http_response(res)?;
41
42 Ok(http_res)
43 }
44}
45
46impl Client for ReqwestClient {
47 type Error = Error;
48
49 fn base_endpoint(&self, path: &str) -> Result<Url, ApiError<Self::Error>> {
50 self.url.join(path).map_err(|e| ApiError::Url {
51 error: e,
52 url: Cow::Borrowed(CRATES_API),
53 path: Cow::Owned(path.to_string()),
54 })
55 }
56
57 fn send(
58 &self,
59 request_builder: Builder,
60 body: Vec<u8>,
61 ) -> Result<http::Response<Bytes>, ApiError<Self::Error>> {
62 let request = request_builder
63 .body(body)
64 .map_err(|error| HttpRequest { error })?;
65
66 self.send_request(request)
67 .map_err(|error| ApiError::Client { error })
68 }
69}
70
71#[derive(Debug, thiserror::Error)]
72pub enum Error {
73 #[error(transparent)]
74 Reqwest {
75 #[from]
76 error: reqwest::Error,
77 },
78}
79
80fn into_http_response(res: reqwest::blocking::Response) -> Result<http::Response<Bytes>, Error> {
81 let mut builder = http::response::Builder::new()
82 .status(res.status())
83 .version(res.version())
84 .url(res.url().clone());
85
86 for (name, value) in res.headers() {
87 builder = builder.header(name, value);
88 }
89
90 let body = res.bytes()?;
91 let response = builder.body(body).unwrap();
92
93 Ok(response)
94}