reqwest_middleware/req_init.rs
1use crate::RequestBuilder;
2
3/// When attached to a [`ClientWithMiddleware`] (generally using [`with_init`]), it is run
4/// whenever the client starts building a request, in the order it was attached.
5///
6/// # Example
7///
8/// ```
9/// use reqwest_middleware::{RequestInitialiser, RequestBuilder};
10///
11/// struct AuthInit;
12///
13/// impl RequestInitialiser for AuthInit {
14/// fn init(&self, req: RequestBuilder) -> RequestBuilder {
15/// req.bearer_auth("my_auth_token")
16/// }
17/// }
18/// ```
19///
20/// [`ClientWithMiddleware`]: crate::ClientWithMiddleware
21/// [`with_init`]: crate::ClientBuilder::with_init
22pub trait RequestInitialiser: 'static + Send + Sync {
23 fn init(&self, req: RequestBuilder) -> RequestBuilder;
24}
25
26impl<F> RequestInitialiser for F
27where
28 F: Send + Sync + 'static + Fn(RequestBuilder) -> RequestBuilder,
29{
30 fn init(&self, req: RequestBuilder) -> RequestBuilder {
31 (self)(req)
32 }
33}
34
35/// A middleware that inserts the value into the [`Extensions`](http::Extensions) during the call.
36///
37/// This is a good way to inject extensions to middleware deeper in the stack
38///
39/// ```
40/// use reqwest::{Client, Request, Response};
41/// use reqwest_middleware::{ClientBuilder, Middleware, Next, Result, Extension};
42/// use http::Extensions;
43///
44/// #[derive(Clone)]
45/// struct LogName(&'static str);
46/// struct LoggingMiddleware;
47///
48/// #[async_trait::async_trait]
49/// impl Middleware for LoggingMiddleware {
50/// async fn handle(
51/// &self,
52/// req: Request,
53/// extensions: &mut Extensions,
54/// next: Next<'_>,
55/// ) -> Result<Response> {
56/// // get the log name or default to "unknown"
57/// let name = extensions
58/// .get()
59/// .map(|&LogName(name)| name)
60/// .unwrap_or("unknown");
61/// println!("[{name}] Request started {req:?}");
62/// let res = next.run(req, extensions).await;
63/// println!("[{name}] Result: {res:?}");
64/// res
65/// }
66/// }
67///
68/// async fn run() {
69/// let reqwest_client = Client::builder().build().unwrap();
70/// let client = ClientBuilder::new(reqwest_client)
71/// .with_init(Extension(LogName("my-client")))
72/// .with(LoggingMiddleware)
73/// .build();
74/// let resp = client.get("https://truelayer.com").send().await.unwrap();
75/// println!("TrueLayer page HTML: {}", resp.text().await.unwrap());
76/// }
77/// ```
78pub struct Extension<T>(pub T);
79
80impl<T: Send + Sync + Clone + 'static> RequestInitialiser for Extension<T> {
81 fn init(&self, req: RequestBuilder) -> RequestBuilder {
82 req.with_extension(self.0.clone())
83 }
84}