1#![cfg_attr(feature = "docs", feature(doc_cfg))]
2#![deny(
3 single_use_lifetimes,
4 missing_debug_implementations,
5 large_assignments,
6 exported_private_dependencies,
7 absolute_paths_not_starting_with_crate,
8 anonymous_parameters,
9 explicit_outlives_requirements,
10 keyword_idents,
11 macro_use_extern_crate,
12 meta_variable_misuse,
13 missing_docs,
14 non_ascii_idents,
15 indirect_structural_match,
16 trivial_casts,
17 trivial_numeric_casts,
18 unsafe_code,
19 unreachable_pub,
20 unused_crate_dependencies,
21 unused_extern_crates,
22 unused_import_braces,
23 unused_lifetimes,
24 unused_qualifications
25)]
26
27mod callback;
37mod error;
38mod request;
39mod response;
40
41use auto_impl::auto_impl;
42pub use callback::{OnHeaderCallback, OnProgressCallback, OnStatusCodeCallback, TransferProgressInfo};
43pub use error::{
44 Error as ResponseError, ErrorBuilder as ResponseErrorBuilder, ErrorKind as ResponseErrorKind, MapError,
45};
46pub use http::{
47 header::{self, HeaderMap, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue},
48 method::{InvalidMethod, Method},
49 status::{InvalidStatusCode, StatusCode},
50 uri::{self, Uri},
51 Extensions, Version,
52};
53use once_cell::sync::OnceCell;
54pub use request::{
55 Request, RequestBody as SyncRequestBody, RequestBuilder, RequestParts, RequestPartsBuilder, UserAgent,
56};
57pub use response::{
58 Metrics, MetricsBuilder, Response, ResponseBody as SyncResponseBody, ResponseBuilder, ResponseParts,
59 Result as ResponseResult,
60};
61use std::{
62 fmt::Debug,
63 io::{Result as IoResult, Seek},
64};
65
66pub type SyncRequest<'r> = Request<'r, SyncRequestBody<'r>>;
68pub type SyncRequestBuilder<'r> = RequestBuilder<'r, SyncRequestBody<'r>>;
70
71pub type SyncResponse = Response<SyncResponseBody>;
73pub type SyncResponseBuilder = ResponseBuilder<SyncResponseBody>;
75pub type SyncResponseResult = ResponseResult<SyncResponseBody>;
77
78#[cfg(feature = "async")]
79mod async_req_resp {
80 pub use super::{request::AsyncRequestBody, response::AsyncResponseBody};
81 use super::{
82 request::{Request, RequestBuilder},
83 response::{Response, ResponseBuilder, Result as ResponseResult},
84 };
85
86 pub type AsyncRequest<'r> = Request<'r, AsyncRequestBody<'r>>;
88 pub type AsyncRequestBuilder<'r> = RequestBuilder<'r, AsyncRequestBody<'r>>;
90
91 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
93 pub type AsyncResponse = Response<AsyncResponseBody>;
94
95 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
97 pub type AsyncResponseBuilder = ResponseBuilder<AsyncResponseBody>;
98
99 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
101 pub type AsyncResponseResult = ResponseResult<AsyncResponseBody>;
102}
103
104#[cfg(feature = "async")]
105pub use {
106 async_req_resp::{
107 AsyncRequest, AsyncRequestBody, AsyncRequestBuilder, AsyncResponse, AsyncResponseBody, AsyncResponseBuilder,
108 AsyncResponseResult,
109 },
110 futures_lite::{AsyncRead, AsyncSeek},
111};
112
113#[cfg(feature = "async")]
114use std::{future::Future, pin::Pin};
115
116#[cfg(feature = "async")]
117type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a + Send>>;
118
119static LIBRARY_USER_AGENT: OnceCell<UserAgent> = OnceCell::new();
120
121#[allow(clippy::result_large_err)]
129pub fn set_library_user_agent(user_agent: UserAgent) -> Result<(), UserAgent> {
130 LIBRARY_USER_AGENT.set(user_agent)
131}
132
133#[auto_impl(&, &mut, Box, Rc, Arc)]
137pub trait HttpCaller: Debug + Send + Sync {
138 fn call(&self, request: &mut SyncRequest<'_>) -> SyncResponseResult;
142
143 #[cfg(feature = "async")]
145 #[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
146 fn async_call<'a>(&'a self, request: &'a mut AsyncRequest<'_>) -> BoxFuture<'a, AsyncResponseResult>;
147
148 #[inline]
150 fn is_resolved_ip_addrs_supported(&self) -> bool {
151 false
152 }
153
154 #[inline]
156 fn is_response_metrics_supported(&self) -> bool {
157 false
158 }
159}
160
161pub trait Reset {
165 fn reset(&mut self) -> IoResult<()>;
169}
170
171impl<T: Seek> Reset for T {
172 #[inline]
173 fn reset(&mut self) -> IoResult<()> {
174 self.rewind()?;
175 Ok(())
176 }
177}
178
179#[cfg(feature = "async")]
183#[cfg_attr(feature = "docs", doc(cfg(feature = "async")))]
184pub trait AsyncReset {
185 fn reset(&mut self) -> BoxFuture<IoResult<()>>;
189}
190
191#[cfg(feature = "async")]
192impl<T: AsyncSeek + Unpin + Send + Sync> AsyncReset for T {
193 #[inline]
194 fn reset(&mut self) -> BoxFuture<IoResult<()>> {
195 use std::io::SeekFrom;
196 use futures_lite::io::AsyncSeekExt;
197
198 Box::pin(async move {
199 self.seek(SeekFrom::Start(0)).await?;
200 Ok(())
201 })
202 }
203}
204
205pub mod prelude {
207 pub use super::{HttpCaller, Metrics, Reset};
208
209 #[cfg(feature = "async")]
210 pub use super::AsyncReset;
211}