Skip to content

Commit 6c6170b

Browse files
Marwesseanmonstar
authored andcommitted
feat: Make encoding_rs an optional dependency called charset
Closes #1785
1 parent d1022b3 commit 6c6170b

File tree

5 files changed

+49
-7
lines changed

5 files changed

+49
-7
lines changed

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ features = [
2727
]
2828

2929
[features]
30-
default = ["default-tls", "http2", "macos-system-configuration"]
30+
default = ["default-tls", "charset", "http2", "macos-system-configuration"]
3131

3232
# Note: this doesn't enable the 'native-tls' feature, which adds specific
3333
# functionality for it.
@@ -47,6 +47,8 @@ rustls-tls-native-roots = ["dep:rustls-native-certs", "__rustls"]
4747

4848
blocking = ["futures-channel/sink", "futures-util/io", "futures-util/sink", "tokio/rt-multi-thread", "tokio/sync"]
4949

50+
charset = ["dep:encoding_rs"]
51+
5052
cookies = ["dep:cookie_crate", "dep:cookie_store"]
5153

5254
gzip = ["dep:async-compression", "async-compression?/gzip", "dep:tokio-util"]
@@ -60,7 +62,7 @@ json = ["dep:serde_json"]
6062
multipart = ["dep:mime_guess"]
6163

6264
# Deprecated, remove this feature while bumping minor versions.
63-
trust-dns = ["dep:trust-dns-resolver"]
65+
trust-dns = []
6466
hickory-dns = ["dep:hickory-resolver"]
6567

6668
stream = ["tokio/fs", "dep:tokio-util", "dep:wasm-streams"]
@@ -107,7 +109,7 @@ serde_json = { version = "1.0", optional = true }
107109
mime_guess = { version = "2.0", default-features = false, optional = true }
108110

109111
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
110-
encoding_rs = "0.8"
112+
encoding_rs = { version = "0.8", optional = true }
111113
http-body = "1"
112114
http-body-util = "0.1"
113115
hyper = { version = "1", features = ["http1", "client"] }

src/async_impl/response.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ use std::net::SocketAddr;
33
use std::pin::Pin;
44

55
use bytes::Bytes;
6-
use encoding_rs::{Encoding, UTF_8};
76
use http_body_util::BodyExt;
87
use hyper::{HeaderMap, StatusCode, Version};
98
use hyper_util::client::legacy::connect::HttpInfo;
10-
use mime::Mime;
119
#[cfg(feature = "json")]
1210
use serde::de::DeserializeOwned;
1311
#[cfg(feature = "json")]
@@ -21,6 +19,11 @@ use crate::async_impl::body::ResponseBody;
2119
#[cfg(feature = "cookies")]
2220
use crate::cookie;
2321

22+
#[cfg(feature = "charset")]
23+
use encoding_rs::{Encoding, UTF_8};
24+
#[cfg(feature = "charset")]
25+
use mime::Mime;
26+
2427
/// A Response to a submitted `Request`.
2528
pub struct Response {
2629
pub(super) res: hyper::Response<Decoder>,
@@ -135,6 +138,11 @@ impl Response {
135138
///
136139
/// Note that the BOM is stripped from the returned String.
137140
///
141+
/// # Note
142+
///
143+
/// If the `charset` feature is disabled the method will only attempt to decode the
144+
/// response as UTF-8, regardless of the given `Content-Type`
145+
///
138146
/// # Example
139147
///
140148
/// ```
@@ -149,7 +157,17 @@ impl Response {
149157
/// # }
150158
/// ```
151159
pub async fn text(self) -> crate::Result<String> {
152-
self.text_with_charset("utf-8").await
160+
#[cfg(feature = "charset")]
161+
{
162+
self.text_with_charset("utf-8").await
163+
}
164+
165+
#[cfg(not(feature = "charset"))]
166+
{
167+
let full = self.bytes().await?;
168+
let text = String::from_utf8_lossy(&full);
169+
Ok(text.into_owned())
170+
}
153171
}
154172

155173
/// Get the full response text given a specific encoding.
@@ -164,6 +182,10 @@ impl Response {
164182
///
165183
/// [`encoding_rs`]: https://docs.rs/encoding_rs/0.8/encoding_rs/#relationship-with-windows-code-pages
166184
///
185+
/// # Optional
186+
///
187+
/// This requires the optional `encoding_rs` feature enabled.
188+
///
167189
/// # Example
168190
///
169191
/// ```
@@ -177,6 +199,8 @@ impl Response {
177199
/// # Ok(())
178200
/// # }
179201
/// ```
202+
#[cfg(feature = "charset")]
203+
#[cfg_attr(docsrs, doc(cfg(feature = "charset")))]
180204
pub async fn text_with_charset(self, default_encoding: &str) -> crate::Result<String> {
181205
let content_type = self
182206
.headers()

src/blocking/response.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,11 @@ impl Response {
270270
/// Encoding is determined from the `charset` parameter of `Content-Type` header,
271271
/// and defaults to `utf-8` if not presented.
272272
///
273+
/// # Note
274+
///
275+
/// If the `charset` feature is disabled the method will only attempt to decode the
276+
/// response as UTF-8, regardless of the given `Content-Type`
277+
///
273278
/// # Example
274279
///
275280
/// ```rust
@@ -280,7 +285,10 @@ impl Response {
280285
/// # }
281286
/// ```
282287
pub fn text(self) -> crate::Result<String> {
283-
self.text_with_charset("utf-8")
288+
wait::timeout(self.inner.text(), self.timeout).map_err(|e| match e {
289+
wait::Waited::TimedOut(e) => crate::error::decode(e),
290+
wait::Waited::Inner(e) => e,
291+
})
284292
}
285293

286294
/// Get the response text given a specific encoding.
@@ -293,6 +301,10 @@ impl Response {
293301
///
294302
/// [`encoding_rs`]: https://docs.rs/encoding_rs/0.8/encoding_rs/#relationship-with-windows-code-pages
295303
///
304+
/// # Optional
305+
///
306+
/// This requires the optional `charset` feature enabled.
307+
///
296308
/// # Example
297309
///
298310
/// ```rust
@@ -303,6 +315,8 @@ impl Response {
303315
/// # Ok(())
304316
/// # }
305317
/// ```
318+
#[cfg(feature = "charset")]
319+
#[cfg_attr(docsrs, doc(cfg(feature = "charset")))]
306320
pub fn text_with_charset(self, default_encoding: &str) -> crate::Result<String> {
307321
wait::timeout(self.inner.text_with_charset(default_encoding), self.timeout).map_err(|e| {
308322
match e {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
//! - **rustls-tls-native-roots**: Enables TLS functionality provided by `rustls`,
194194
//! while using root certificates from the `rustls-native-certs` crate.
195195
//! - **blocking**: Provides the [blocking][] client API.
196+
//! - **charset** *(enabled by default)*: Improved support for decoding text.
196197
//! - **cookies**: Provides cookie session support.
197198
//! - **gzip**: Provides response body gzip decompression.
198199
//! - **brotli**: Provides response body brotli decompression.

tests/blocking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fn test_response_text() {
2222
}
2323

2424
#[test]
25+
#[cfg(feature = "charset")]
2526
fn test_response_non_utf_8_text() {
2627
let server = server::http(move |_req| async {
2728
http::Response::builder()

0 commit comments

Comments
 (0)