diff --git a/README.md b/README.md index cd12dec..b987255 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ to allow for client middleware chains. This crate provides functionality for building and running middleware but no middleware implementations. This repository also contains a couple of useful concrete middleware crates: -* [`reqwest-retry`](https://crates.io/crates/reqwest-retry): retry failed requests. -* [`reqwest-tracing`](https://crates.io/crates/reqwest-tracing): +- [`reqwest-retry`](https://crates.io/crates/reqwest-retry): retry failed requests. +- [`reqwest-tracing`](https://crates.io/crates/reqwest-tracing): [`tracing`](https://crates.io/crates/tracing) integration, optional opentelemetry support. ## Overview @@ -29,10 +29,12 @@ reqwest-middleware = "0.1.6" reqwest-retry = "0.1.5" reqwest-tracing = "0.2.3" tokio = { version = "1.12.0", features = ["macros", "rt-multi-thread"] } +tower = "0.4" ``` ```rust -use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; +use reqwest::Response; +use reqwest_middleware::{ClientBuilder, ClientWithMiddleware, Error, MiddlewareRequest, RequestInitialiser, ReqwestService}; use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff}; use reqwest_tracing::TracingMiddleware; @@ -49,7 +51,12 @@ async fn main() { run(client).await; } -async fn run(client: ClientWithMiddleware) { +async fn run(client: ClientWithMiddleware) +where + M: tower::Layer, + M::Service: tower::Service, + I: RequestInitialiser, +{ client .get("https://truelayer.com") .header("foo", "bar") diff --git a/reqwest-middleware/Cargo.toml b/reqwest-middleware/Cargo.toml index c1034cb..5b969d1 100644 --- a/reqwest-middleware/Cargo.toml +++ b/reqwest-middleware/Cargo.toml @@ -19,6 +19,7 @@ serde = "1" task-local-extensions = "0.1.1" thiserror = "1" tower = { version = "0.4", features = ["util"] } +futures = "0.3" [dev-dependencies] reqwest = "0.11" diff --git a/reqwest-middleware/src/client.rs b/reqwest-middleware/src/client.rs index e0348d6..033179c 100644 --- a/reqwest-middleware/src/client.rs +++ b/reqwest-middleware/src/client.rs @@ -1,80 +1,62 @@ +use futures::future::BoxFuture; +use futures::FutureExt; use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use reqwest::multipart::Form; use reqwest::{Body, Client, IntoUrl, Method, Request, Response}; use serde::Serialize; use std::convert::TryFrom; use std::fmt::{self, Display}; +use std::task::{Context, Poll}; use std::time::Duration; use task_local_extensions::Extensions; use tower::layer::util::{Identity, Stack}; use tower::{Layer, Service, ServiceBuilder, ServiceExt}; -use crate::error::Result; -use crate::{Error, MiddlewareRequest, RequestInitialiser}; +use crate::{Error, MiddlewareRequest, RequestInitialiser, RequestStack}; /// A `ClientBuilder` is used to build a [`ClientWithMiddleware`]. /// /// [`ClientWithMiddleware`]: crate::ClientWithMiddleware -pub struct ClientBuilder { +pub struct ClientBuilder { client: Client, middleware_stack: ServiceBuilder, - initialiser_stack: (), + initialiser_stack: I, } -impl ClientBuilder { +impl ClientBuilder { pub fn new(client: Client) -> Self { ClientBuilder { client, middleware_stack: ServiceBuilder::new(), - initialiser_stack: (), + initialiser_stack: Identity::new(), } } } -impl ClientBuilder { +impl ClientBuilder { /// Convenience method to attach middleware. - /// - /// If you need to keep a reference to the middleware after attaching, use [`with_arc`]. - /// - /// [`with_arc`]: Self::with_arc - pub fn layer(self, layer: T) -> ClientBuilder> { + pub fn with(self, layer: T) -> ClientBuilder, I> { ClientBuilder { client: self.client, middleware_stack: self.middleware_stack.layer(layer), - initialiser_stack: (), + initialiser_stack: self.initialiser_stack, } } - // /// Add middleware to the chain. [`with`] is more ergonomic if you don't need the `Arc`. - // /// - // /// [`with`]: Self::with - // pub fn with_arc(mut self, middleware: Arc) -> Self { - // self.middleware_stack.push(middleware); - // self - // } - - // /// Convenience method to attach a request initialiser. - // /// - // /// If you need to keep a reference to the initialiser after attaching, use [`with_arc_init`]. - // /// - // /// [`with_arc_init`]: Self::with_arc_init - // pub fn with_init(self, initialiser: I) -> Self - // where - // I: RequestInitialiser, - // { - // self.with_arc_init(Arc::new(initialiser)) - // } - - // /// Add a request initialiser to the chain. [`with_init`] is more ergonomic if you don't need the `Arc`. - // /// - // /// [`with_init`]: Self::with_init - // pub fn with_arc_init(mut self, initialiser: Arc) -> Self { - // self.initialiser_stack.push(initialiser); - // self - // } + /// Convenience method to attach a request initialiser. + pub fn with_init(self, initialiser: T) -> ClientBuilder> { + ClientBuilder { + client: self.client, + middleware_stack: self.middleware_stack, + initialiser_stack: RequestStack { + inner: initialiser, + outer: self.initialiser_stack, + }, + } + } /// Returns a `ClientWithMiddleware` using this builder configuration. - pub fn build(self) -> ClientWithMiddleware { + pub fn build(self) -> ClientWithMiddleware { ClientWithMiddleware { inner: self.client, middleware_stack: self.middleware_stack, @@ -92,21 +74,7 @@ pub struct ClientWithMiddleware { initialiser_stack: I, } -// impl> ClientWithMiddleware -// where -// M::Service: Service, -// { -// /// See [`ClientBuilder`] for a more ergonomic way to build `ClientWithMiddleware` instances. -// pub fn new(client: Client, middleware_stack: M) -> Self { -// ClientWithMiddleware { -// inner: client, -// middleware_stack, -// initialiser_stack: (), -// } -// } -// } - -impl, I: RequestInitialiser> ClientWithMiddleware +impl, I: RequestInitialiser> ClientWithMiddleware where M::Service: Service, { @@ -181,28 +149,26 @@ pub struct RequestBuilder<'client, M, I> { extensions: Extensions, } -pub type BoxFuture<'a, T> = std::pin::Pin + Send + 'a>>; - #[derive(Clone)] -pub struct ReqService(Client); +pub struct ReqwestService(Client); -impl Service for ReqService { +impl Service for ReqwestService { type Response = Response; type Error = Error; - type Future = BoxFuture<'static, Result>; + type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> std::task::Poll> { - std::task::Poll::Ready(Ok(())) + fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) } fn call(&mut self, req: MiddlewareRequest) -> Self::Future { let req = req.request; let client = self.0.clone(); - Box::pin(async move { client.execute(req).await.map_err(Error::from) }) + async move { client.execute(req).await.map_err(Error::from) }.boxed() } } -impl, I: RequestInitialiser> RequestBuilder<'_, M, I> +impl, I: RequestInitialiser> RequestBuilder<'_, M, I> where M::Service: Service, { @@ -304,7 +270,7 @@ where &mut self.extensions } - pub async fn send(self) -> Result { + pub async fn send(self) -> Result { let Self { inner, client, @@ -313,7 +279,7 @@ where let req = inner.build()?; client .middleware_stack - .service(ReqService(client.inner.clone())) + .service(ReqwestService(client.inner.clone())) .oneshot(MiddlewareRequest { request: req, extensions, diff --git a/reqwest-middleware/src/error.rs b/reqwest-middleware/src/error.rs index c276578..bbd2234 100644 --- a/reqwest-middleware/src/error.rs +++ b/reqwest-middleware/src/error.rs @@ -1,7 +1,5 @@ use thiserror::Error; -pub type Result = std::result::Result; - #[derive(Error, Debug)] pub enum Error { /// There was an error running some middleware diff --git a/reqwest-middleware/src/lib.rs b/reqwest-middleware/src/lib.rs index a4ea824..d0fd72c 100644 --- a/reqwest-middleware/src/lib.rs +++ b/reqwest-middleware/src/lib.rs @@ -7,27 +7,31 @@ //! //! ``` //! use reqwest::{Client, Request, Response}; -//! use reqwest_middleware::{ClientBuilder, Middleware, Next, Result}; +//! use reqwest_middleware::{ClientBuilder, Error, Extension, MiddlewareRequest}; //! use task_local_extensions::Extensions; -//! use futures::FutureExt; +//! use futures::future::{BoxFuture, FutureExt}; //! use std::task::{Context, Poll}; //! //! struct LoggingLayer; //! struct LoggingService(S); -//! +//! //! impl tower::Layer for LoggingLayer { //! type Service = LoggingService; -//! +//! //! fn layer(&self, inner: S) -> Self::Service { //! LoggingService(inner) //! } //! } //! -//! impl> tower::Service for LoggingService { -//! type Response = S::Response; -//! type Error = S::Error; -//! type Future = futures::BoxFuture<'static, Result>; -//! +//! impl tower::Service for LoggingService +//! where +//! S: tower::Service, +//! S::Future: Send + 'static, +//! { +//! type Response = Response; +//! type Error = Error; +//! type Future = BoxFuture<'static, Result>; +//! //! fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { //! self.0.poll_ready(cx) //! } @@ -46,7 +50,7 @@ //! async fn run() { //! let reqwest_client = Client::builder().build().unwrap(); //! let client = ClientBuilder::new(reqwest_client) -//! .layer(LoggingLayer) +//! .with(LoggingLayer) //! .build(); //! let resp = client.get("https://truelayer.com").send().await.unwrap(); //! println!("TrueLayer page HTML: {}", resp.text().await.unwrap()); @@ -69,9 +73,9 @@ mod client; mod error; mod req_init; -pub use client::{ClientBuilder, ClientWithMiddleware, ReqService, RequestBuilder}; -pub use error::{Error, Result}; -pub use req_init::{Extension, RequestInitialiser}; +pub use client::{ClientBuilder, ClientWithMiddleware, RequestBuilder, ReqwestService}; +pub use error::Error; +pub use req_init::{Extension, RequestInitialiser, RequestStack}; pub struct MiddlewareRequest { pub request: reqwest::Request, diff --git a/reqwest-middleware/src/req_init.rs b/reqwest-middleware/src/req_init.rs index 6b15fd0..75d8aa3 100644 --- a/reqwest-middleware/src/req_init.rs +++ b/reqwest-middleware/src/req_init.rs @@ -1,5 +1,6 @@ use reqwest::RequestBuilder; use task_local_extensions::Extensions; +use tower::layer::util::Identity; /// When attached to a [`ClientWithMiddleware`] (generally using [`with_init`]), it is run /// whenever the client starts building a request, in the order it was attached. @@ -7,12 +8,14 @@ use task_local_extensions::Extensions; /// # Example /// /// ``` -/// use reqwest_middleware::{RequestInitialiser, MiddlewareRequest}; +/// use reqwest::RequestBuilder; +/// use reqwest_middleware::RequestInitialiser; +/// use task_local_extensions::Extensions; /// /// struct AuthInit; /// /// impl RequestInitialiser for AuthInit { -/// fn init(&self, req: MiddlewareRequest) -> MiddlewareRequest { +/// fn init(&self, req: RequestBuilder, ext: &mut Extensions) -> RequestBuilder { /// req.bearer_auth("my_auth_token") /// } /// } @@ -24,51 +27,82 @@ pub trait RequestInitialiser: 'static + Send + Sync { fn init(&self, req: RequestBuilder, ext: &mut Extensions) -> RequestBuilder; } -impl RequestInitialiser for () { +impl RequestInitialiser for Identity { fn init(&self, req: RequestBuilder, _: &mut Extensions) -> RequestBuilder { req } } -// impl RequestInitialiser for F -// where -// F: Send + Sync + 'static + Fn(MiddlewareRequest) -> MiddlewareRequest, -// { -// fn init(&self, req: RequestBuilder, ext: &mut Extensions) -> RequestBuilder { -// (self)(req) -// } -// } +/// Two [`RequestInitialiser`]s chained together. +#[derive(Clone)] +pub struct RequestStack { + pub(crate) inner: Inner, + pub(crate) outer: Outer, +} + +impl RequestInitialiser for RequestStack +where + I: RequestInitialiser, + O: RequestInitialiser, +{ + fn init(&self, req: RequestBuilder, ext: &mut Extensions) -> RequestBuilder { + let req = self.inner.init(req, ext); + self.outer.init(req, ext) + } +} /// A middleware that inserts the value into the [`Extensions`](task_local_extensions::Extensions) during the call. /// /// This is a good way to inject extensions to middleware deeper in the stack /// /// ``` -/// use reqwest::{Client, Request, Response}; -/// use reqwest_middleware::{ClientBuilder, Middleware, Next, Result, Extension}; +/// use reqwest::{Client, RequestBuilder, Response}; +/// use reqwest_middleware::{ClientBuilder, Error, Extension, MiddlewareRequest}; /// use task_local_extensions::Extensions; +/// use futures::future::{BoxFuture, FutureExt}; +/// use std::task::{Context, Poll}; /// /// #[derive(Clone)] /// struct LogName(&'static str); -/// struct LoggingMiddleware; /// -/// #[async_trait::async_trait] -/// impl Middleware for LoggingMiddleware { -/// async fn handle( -/// &self, -/// req: Request, -/// extensions: &mut Extensions, -/// next: Next<'_>, -/// ) -> Result { +/// struct LoggingLayer; +/// struct LoggingService(S); +/// +/// impl tower::Layer for LoggingLayer { +/// type Service = LoggingService; +/// +/// fn layer(&self, inner: S) -> Self::Service { +/// LoggingService(inner) +/// } +/// } +/// +/// impl tower::Service for LoggingService +/// where +/// S: tower::Service, +/// S::Future: Send + 'static, +/// { +/// type Response = Response; +/// type Error = Error; +/// type Future = BoxFuture<'static, Result>; +/// +/// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { +/// self.0.poll_ready(cx) +/// } +/// +/// fn call(&mut self, req: MiddlewareRequest) -> Self::Future { /// // get the log name or default to "unknown" -/// let name = extensions +/// let name = req +/// .extensions /// .get() /// .map(|&LogName(name)| name) /// .unwrap_or("unknown"); -/// println!("[{name}] Request started {req:?}"); -/// let res = next.run(req, extensions).await; -/// println!("[{name}] Result: {res:?}"); -/// res +/// println!("[{name}] Request started {:?}", &req.request); +/// let fut = self.0.call(req); +/// async move { +/// let res = fut.await; +/// println!("[{name}] Result: {res:?}"); +/// res +/// }.boxed() /// } /// } /// @@ -76,7 +110,7 @@ impl RequestInitialiser for () { /// let reqwest_client = Client::builder().build().unwrap(); /// let client = ClientBuilder::new(reqwest_client) /// .with_init(Extension(LogName("my-client"))) -/// .with(LoggingMiddleware) +/// .with(LoggingLayer) /// .build(); /// let resp = client.get("https://truelayer.com").send().await.unwrap(); /// println!("TrueLayer page HTML: {}", resp.text().await.unwrap()); diff --git a/reqwest-retry/src/lib.rs b/reqwest-retry/src/lib.rs index 6cf81d3..bef3763 100644 --- a/reqwest-retry/src/lib.rs +++ b/reqwest-retry/src/lib.rs @@ -13,7 +13,7 @@ //! // Retry up to 3 times with increasing intervals between attempts. //! let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3); //! let client = ClientBuilder::new(reqwest::Client::new()) -//! .layer(RetryTransientMiddleware::new_with_policy(retry_policy)) +//! .with(RetryTransientMiddleware::new_with_policy(retry_policy)) //! .build(); //! //! client diff --git a/reqwest-retry/src/middleware.rs b/reqwest-retry/src/middleware.rs index 8ac29ee..65f07bd 100644 --- a/reqwest-retry/src/middleware.rs +++ b/reqwest-retry/src/middleware.rs @@ -36,7 +36,7 @@ use tower::{Layer, Service}; /// }; /// /// let retry_transient_middleware = RetryTransientMiddleware::new_with_policy(retry_policy); -/// let client = ClientBuilder::new(Client::new()).layer(retry_transient_middleware).build(); +/// let client = ClientBuilder::new(Client::new()).with(retry_transient_middleware).build(); ///``` /// /// # Note diff --git a/reqwest-retry/tests/all/retry.rs b/reqwest-retry/tests/all/retry.rs index 923d635..ba6bae0 100644 --- a/reqwest-retry/tests/all/retry.rs +++ b/reqwest-retry/tests/all/retry.rs @@ -48,7 +48,7 @@ macro_rules! assert_retry_succeeds_inner { let reqwest_client = Client::builder().build().unwrap(); let client = ClientBuilder::new(reqwest_client) - .layer(RetryTransientMiddleware::new_with_policy( + .with(RetryTransientMiddleware::new_with_policy( ExponentialBackoff { max_n_retries: retry_amount, max_retry_interval: std::time::Duration::from_millis(30), @@ -184,7 +184,7 @@ async fn assert_retry_on_request_timeout() { let reqwest_client = Client::builder().build().unwrap(); let client = ClientBuilder::new(reqwest_client) - .layer(RetryTransientMiddleware::new_with_policy( + .with(RetryTransientMiddleware::new_with_policy( ExponentialBackoff { max_n_retries: 3, max_retry_interval: std::time::Duration::from_millis(100), @@ -239,7 +239,7 @@ async fn assert_retry_on_incomplete_message() { let reqwest_client = Client::builder().build().unwrap(); let client = ClientBuilder::new(reqwest_client) - .layer(RetryTransientMiddleware::new_with_policy( + .with(RetryTransientMiddleware::new_with_policy( ExponentialBackoff { max_n_retries: 3, max_retry_interval: std::time::Duration::from_millis(100), diff --git a/reqwest-tracing/src/lib.rs b/reqwest-tracing/src/lib.rs index 749b817..b7bee26 100644 --- a/reqwest-tracing/src/lib.rs +++ b/reqwest-tracing/src/lib.rs @@ -4,11 +4,11 @@ //! //! The simplest possible usage: //! ```no_run -//! # use reqwest_middleware::Result; +//! # use reqwest_middleware::Error; //! use reqwest_middleware::{ClientBuilder}; //! use reqwest_tracing::TracingMiddleware; //! -//! # async fn example() -> Result<()> { +//! # async fn example() -> Result<(), Error> { //! let reqwest_client = reqwest::Client::builder().build().unwrap(); //! let client = ClientBuilder::new(reqwest_client) //! // Insert the tracing middleware @@ -22,12 +22,12 @@ //! //! To customise the span names use [`OtelName`]. //! ```no_run -//! # use reqwest_middleware::Result; +//! # use reqwest_middleware::Error; //! use reqwest_middleware::{ClientBuilder, Extension}; //! use reqwest_tracing::{ //! TracingMiddleware, OtelName //! }; -//! # async fn example() -> Result<()> { +//! # async fn example() -> Result<(), Error> { //! let reqwest_client = reqwest::Client::builder().build().unwrap(); //! let client = ClientBuilder::new(reqwest_client) //! // Inserts the extension before the request is started @@ -52,7 +52,7 @@ //! //! Note that Opentelemetry tracks start and stop already, there is no need to have a custom builder like this. //! ```rust -//! use reqwest_middleware::Result; +//! use reqwest_middleware::Error; //! use task_local_extensions::Extensions; //! use reqwest::{Request, Response}; //! use reqwest_middleware::ClientBuilder; @@ -70,7 +70,7 @@ //! reqwest_otel_span!(name="example-request", req, time_elapsed = tracing::field::Empty) //! } //! -//! fn on_request_end(span: &Span, outcome: &Result, extension: &mut Extensions) { +//! fn on_request_end(span: &Span, outcome: &Result, extension: &mut Extensions) { //! let time_elapsed = extension.get::().unwrap().elapsed().as_millis() as i64; //! default_on_request_end(span, outcome); //! span.record("time_elapsed", &time_elapsed); @@ -103,18 +103,3 @@ pub use reqwest_otel_span_builder::{ #[doc(hidden)] pub mod reqwest_otel_span_macro; - -#[cfg(test)] -mod tests { - use crate::{TracingMiddleware, DefaultSpanBackend}; - use reqwest_middleware::ClientBuilder; - - #[tokio::test] - async fn compiles() { - let client = ClientBuilder::new(reqwest::Client::new()) - .layer(TracingMiddleware::::new()) - .build(); - let resp = client.get("http://example.com").send().await.unwrap(); - dbg!(resp); - } -} diff --git a/reqwest-tracing/src/middleware.rs b/reqwest-tracing/src/middleware.rs index e9aa1ca..ea69797 100644 --- a/reqwest-tracing/src/middleware.rs +++ b/reqwest-tracing/src/middleware.rs @@ -1,4 +1,7 @@ -use std::{future::Future, task::ready}; +use std::{ + future::Future, + task::{ready, Context, Poll}, +}; use pin_project_lite::pin_project; use reqwest::Response; @@ -65,10 +68,7 @@ where type Error = Error; type Future = TracingMiddlewareFuture; - fn poll_ready( - &mut self, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.service.poll_ready(cx) } @@ -117,16 +117,13 @@ impl>> Fut { type Output = F::Output; - fn poll( - self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll { + fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); let outcome = { let _guard = this.span.enter(); ready!(this.future.poll(cx)) }; S::on_request_end(this.span, &outcome); - std::task::Poll::Ready(outcome) + Poll::Ready(outcome) } } diff --git a/reqwest-tracing/src/reqwest_otel_span_builder.rs b/reqwest-tracing/src/reqwest_otel_span_builder.rs index 6fde890..934ab5c 100644 --- a/reqwest-tracing/src/reqwest_otel_span_builder.rs +++ b/reqwest-tracing/src/reqwest_otel_span_builder.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use reqwest::header::{HeaderMap, HeaderValue}; use reqwest::{Request, Response, StatusCode as RequestStatusCode, Url}; -use reqwest_middleware::{Error, Result}; +use reqwest_middleware::Error; use task_local_extensions::Extensions; use tracing::Span; @@ -44,12 +44,12 @@ pub trait ReqwestOtelSpanBackend { fn on_request_start(req: &Request, extension: &mut Extensions) -> Span; /// Runs after the request call has executed. - fn on_request_end(span: &Span, outcome: &Result); + fn on_request_end(span: &Span, outcome: &Result); } /// Populates default success/failure fields for a given [`reqwest_otel_span!`] span. #[inline] -pub fn default_on_request_end(span: &Span, outcome: &Result) { +pub fn default_on_request_end(span: &Span, outcome: &Result) { match outcome { Ok(res) => default_on_request_success(span, res), Err(err) => default_on_request_failure(span, err), @@ -103,7 +103,7 @@ impl ReqwestOtelSpanBackend for DefaultSpanBackend { reqwest_otel_span!(name = name, req) } - fn on_request_end(span: &Span, outcome: &Result) { + fn on_request_end(span: &Span, outcome: &Result) { default_on_request_end(span, outcome) } } @@ -128,7 +128,7 @@ impl ReqwestOtelSpanBackend for SpanBackendWithUrl { reqwest_otel_span!(name = name, req, http.url = %remove_credentials(req.url())) } - fn on_request_end(span: &Span, outcome: &Result) { + fn on_request_end(span: &Span, outcome: &Result) { default_on_request_end(span, outcome) } } @@ -156,28 +156,28 @@ fn get_span_status(request_status: RequestStatusCode) -> Option<&'static str> { /// /// Usage: /// ```no_run -/// # use reqwest_middleware::Result; +/// # use reqwest_middleware::Error; /// use reqwest_middleware::{ClientBuilder, Extension}; /// use reqwest_tracing::{ /// TracingMiddleware, OtelName /// }; -/// # async fn example() -> Result<()> { +/// # async fn example() -> Result<(), Error> { /// let reqwest_client = reqwest::Client::builder().build().unwrap(); /// let client = ClientBuilder::new(reqwest_client) -/// // Inserts the extension before the request is started -/// .with_init(Extension(OtelName("my-client".into()))) -/// // Makes use of that extension to specify the otel name -/// .with(TracingMiddleware::default()) -/// .build(); +/// // Inserts the extension before the request is started +/// .with_init(Extension(OtelName("my-client".into()))) +/// // Makes use of that extension to specify the otel name +/// .with(TracingMiddleware::default()) +/// .build(); /// /// let resp = client.get("https://truelayer.com").send().await.unwrap(); /// /// // Or specify it on the individual request (will take priority) /// let resp = client.post("https://api.truelayer.com/payment") /// .with_extension(OtelName("POST /payment".into())) -/// .send() -/// .await -/// .unwrap(); +/// .send() +/// .await +/// .unwrap(); /// # Ok(()) /// # } /// ``` diff --git a/reqwest-tracing/src/reqwest_otel_span_macro.rs b/reqwest-tracing/src/reqwest_otel_span_macro.rs index 5c1237f..e3312dd 100644 --- a/reqwest-tracing/src/reqwest_otel_span_macro.rs +++ b/reqwest-tracing/src/reqwest_otel_span_macro.rs @@ -30,7 +30,7 @@ /// The second argument passed to [`reqwest_otel_span!`](crate::reqwest_otel_span) is a reference to an [`reqwest::Request`]. /// /// ```rust -/// use reqwest_middleware::Result; +/// use reqwest_middleware::Error; /// use task_local_extensions::Extensions; /// use reqwest::{Request, Response}; /// use reqwest_tracing::{ @@ -45,7 +45,7 @@ /// reqwest_otel_span!(name = "reqwest-http-request", req) /// } /// -/// fn on_request_end(span: &Span, outcome: &Result, _extension: &mut Extensions) { +/// fn on_request_end(span: &Span, outcome: &Result) { /// default_on_request_end(span, outcome) /// } /// }