From 522216e890ccb13c43fb0d92af9598b3bedaaec5 Mon Sep 17 00:00:00 2001 From: Aleksey Sidorov Date: Mon, 19 Aug 2024 13:14:25 +0000 Subject: [PATCH] feat: Add `impl Service>` for `Client` and `&'_ Client` (#2356) --- CHANGELOG.md | 1 + src/async_impl/client.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0860163..b8c54903f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Unreleased - Implement `danger_accept_invalid_hostnames` for `rustls`. +- Add `impl Service>` for `Client` and `&'_ Client`. ## v0.12.5 diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index 0a7281c42..d7defc578 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -2161,6 +2161,62 @@ impl tower_service::Service for &'_ Client { } } +impl tower_service::Service> for Client { + type Response = http::Response; + type Error = crate::Error; + type Future = MappedPending; + + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: http::Request) -> Self::Future { + match req.try_into() { + Ok(req) => MappedPending::new(self.execute_request(req)), + Err(err) => MappedPending::new(Pending::new_err(err)), + } + } +} + +impl tower_service::Service> for &'_ Client { + type Response = http::Response; + type Error = crate::Error; + type Future = MappedPending; + + fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: http::Request) -> Self::Future { + match req.try_into() { + Ok(req) => MappedPending::new(self.execute_request(req)), + Err(err) => MappedPending::new(Pending::new_err(err)), + } + } +} + +pin_project! { + pub struct MappedPending { + #[pin] + inner: Pending, + } +} + +impl MappedPending { + fn new(inner: Pending) -> MappedPending { + Self { inner } + } +} + +impl Future for MappedPending { + type Output = Result, crate::Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let inner = self.project().inner; + inner.poll(cx).map_ok(Into::into) + } +} + impl fmt::Debug for ClientBuilder { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut builder = f.debug_struct("ClientBuilder");