From bc38da8c33e72ed77dc35446650043eeb4c9e6c1 Mon Sep 17 00:00:00 2001 From: gngpp Date: Fri, 20 Feb 2026 16:57:07 +0800 Subject: [PATCH 1/2] refactor(response): merge `text` and `text_with_charset` into a single method --- python/rnet/__init__.pyi | 9 +---- python/rnet/blocking.py | 10 +---- src/client/resp/http.rs | 84 ++++++++++++++++++++-------------------- 3 files changed, 45 insertions(+), 58 deletions(-) diff --git a/python/rnet/__init__.pyi b/python/rnet/__init__.pyi index 836d68db..2b753044 100644 --- a/python/rnet/__init__.pyi +++ b/python/rnet/__init__.pyi @@ -391,14 +391,9 @@ class Response: Get the response into a `Streamer` of `bytes` from the body. """ - async def text(self) -> str: + async def text(self, encoding: str | None = None) -> str: r""" - Get the text content of the response. - """ - - async def text_with_charset(self, encoding: str) -> str: - r""" - Get the full response text given a specific encoding. + Get the text content with the response encoding, defaulting to utf-8 when unspecified. """ async def json(self) -> Any: diff --git a/python/rnet/blocking.py b/python/rnet/blocking.py index 58f4a0eb..837f06fd 100644 --- a/python/rnet/blocking.py +++ b/python/rnet/blocking.py @@ -88,15 +88,9 @@ def stream(self) -> Streamer: """ ... - def text(self) -> str: + def text(self, encoding: str | None = None) -> str: r""" - Get the text content of the response. - """ - ... - - def text_with_charset(self, encoding: str) -> str: - r""" - Get the full response text given a specific encoding. + Get the text content with the response encoding, defaulting to utf-8 when unspecified. """ ... diff --git a/src/client/resp/http.rs b/src/client/resp/http.rs index c7a04bd2..4673daca 100644 --- a/src/client/resp/http.rs +++ b/src/client/resp/http.rs @@ -219,28 +219,28 @@ impl Response { .map_err(Into::into) } - /// Get the text content of the response. - pub async fn text(&self, #[pyo3(cancel_handle)] cancel: CancelHandle) -> PyResult { - let fut = self - .clone() - .cache_response() - .and_then(ResponseExt::text) - .map_err(Into::into); - NoGIL::new(fut, cancel).await - } - - /// Get the full response text given a specific encoding. - #[pyo3(signature = (encoding))] - pub async fn text_with_charset( + /// Get the text content with the response encoding, defaulting to utf-8 when unspecified. + #[pyo3(signature = (encoding = None))] + pub async fn text( &self, #[pyo3(cancel_handle)] cancel: CancelHandle, - encoding: PyBackedStr, + encoding: Option, ) -> PyResult { - let fut = self - .clone() - .cache_response() - .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) - .map_err(Into::into); + let this = self.clone(); + let fut = async move { + match encoding { + Some(encoding) => this + .cache_response() + .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) + .await + .map_err(Into::into), + None => this + .cache_response() + .and_then(ResponseExt::text) + .await + .map_err(Into::into), + } + }; NoGIL::new(fut, cancel).await } @@ -392,30 +392,28 @@ impl BlockingResponse { self.0.stream() } - /// Get the text content of the response. - pub fn text(&self, py: Python) -> PyResult { - py.detach(|| { - let fut = self - .0 - .clone() - .cache_response() - .and_then(ResponseExt::text) - .map_err(Into::into); - pyo3_async_runtimes::tokio::get_runtime().block_on(fut) - }) - } - - /// Get the full response text given a specific encoding. - #[pyo3(signature = (encoding))] - pub fn text_with_charset(&self, py: Python, encoding: PyBackedStr) -> PyResult { - py.detach(|| { - let fut = self - .0 - .clone() - .cache_response() - .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) - .map_err(Into::into); - pyo3_async_runtimes::tokio::get_runtime().block_on(fut) + /// Get the text content with the response encoding, defaulting to utf-8 when unspecified. + #[pyo3(signature = (encoding = None))] + pub fn text(&self, py: Python, encoding: Option) -> PyResult { + py.detach(|| match encoding { + Some(encoding) => { + let fut = self + .0 + .clone() + .cache_response() + .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) + .map_err(Into::into); + pyo3_async_runtimes::tokio::get_runtime().block_on(fut) + } + None => { + let fut = self + .0 + .clone() + .cache_response() + .and_then(ResponseExt::text) + .map_err(Into::into); + pyo3_async_runtimes::tokio::get_runtime().block_on(fut) + } }) } From 5310eb3eee9ebb5dba3e41f282602aa2bbab1ad0 Mon Sep 17 00:00:00 2001 From: gngpp Date: Fri, 20 Feb 2026 17:12:45 +0800 Subject: [PATCH 2/2] fmt --- src/client/resp/ext.rs | 21 +++++++----------- src/client/resp/http.rs | 47 ++++++++++++----------------------------- 2 files changed, 21 insertions(+), 47 deletions(-) diff --git a/src/client/resp/ext.rs b/src/client/resp/ext.rs index 95cfd0ee..05b9a390 100644 --- a/src/client/resp/ext.rs +++ b/src/client/resp/ext.rs @@ -1,4 +1,5 @@ use bytes::Bytes; +use pyo3::pybacked::PyBackedStr; use crate::error::Error; @@ -8,11 +9,8 @@ use crate::error::Error; /// This trait wraps the underlying [`wreq::Response`] methods and converts their errors to our /// custom `Error` type. pub trait ResponseExt { - /// Returns an error if the body cannot be decoded as valid UTF-8. - async fn text(self) -> Result; - /// Returns an error if the encoding is unsupported or decoding fails. - async fn text_with_charset(self, encoding: impl AsRef) -> Result; + async fn text(self, encoding: Option) -> Result; /// Returns an error if the body is not valid JSON or cannot be deserialized into `T`. async fn json(self) -> Result; @@ -23,15 +21,12 @@ pub trait ResponseExt { impl ResponseExt for wreq::Response { #[inline] - async fn text(self) -> Result { - self.text().await.map_err(Error::Library) - } - - #[inline] - async fn text_with_charset(self, encoding: impl AsRef) -> Result { - self.text_with_charset(encoding) - .await - .map_err(Error::Library) + async fn text(self, encoding: Option) -> Result { + match encoding { + Some(encoding) => self.text_with_charset(encoding).await, + None => self.text().await, + } + .map_err(Error::Library) } #[inline] diff --git a/src/client/resp/http.rs b/src/client/resp/http.rs index 4673daca..9ed82819 100644 --- a/src/client/resp/http.rs +++ b/src/client/resp/http.rs @@ -226,21 +226,11 @@ impl Response { #[pyo3(cancel_handle)] cancel: CancelHandle, encoding: Option, ) -> PyResult { - let this = self.clone(); - let fut = async move { - match encoding { - Some(encoding) => this - .cache_response() - .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) - .await - .map_err(Into::into), - None => this - .cache_response() - .and_then(ResponseExt::text) - .await - .map_err(Into::into), - } - }; + let fut = self + .clone() + .cache_response() + .and_then(|resp| ResponseExt::text(resp, encoding)) + .map_err(Into::into); NoGIL::new(fut, cancel).await } @@ -395,25 +385,14 @@ impl BlockingResponse { /// Get the text content with the response encoding, defaulting to utf-8 when unspecified. #[pyo3(signature = (encoding = None))] pub fn text(&self, py: Python, encoding: Option) -> PyResult { - py.detach(|| match encoding { - Some(encoding) => { - let fut = self - .0 - .clone() - .cache_response() - .and_then(|resp| ResponseExt::text_with_charset(resp, encoding)) - .map_err(Into::into); - pyo3_async_runtimes::tokio::get_runtime().block_on(fut) - } - None => { - let fut = self - .0 - .clone() - .cache_response() - .and_then(ResponseExt::text) - .map_err(Into::into); - pyo3_async_runtimes::tokio::get_runtime().block_on(fut) - } + py.detach(|| { + let fut = self + .0 + .clone() + .cache_response() + .and_then(|resp| ResponseExt::text(resp, encoding)) + .map_err(Into::into); + pyo3_async_runtimes::tokio::get_runtime().block_on(fut) }) }