Skip to content

Commit

Permalink
feat: Make encoding_rs an optional dependency called charset
Browse files Browse the repository at this point in the history
Closes #1785
  • Loading branch information
Marwes authored and seanmonstar committed Mar 20, 2024
1 parent d1022b3 commit 6c6170b
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ features = [
]

[features]
default = ["default-tls", "http2", "macos-system-configuration"]
default = ["default-tls", "charset", "http2", "macos-system-configuration"]

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

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

charset = ["dep:encoding_rs"]

cookies = ["dep:cookie_crate", "dep:cookie_store"]

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

# Deprecated, remove this feature while bumping minor versions.
trust-dns = ["dep:trust-dns-resolver"]
trust-dns = []
hickory-dns = ["dep:hickory-resolver"]

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

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
encoding_rs = "0.8"
encoding_rs = { version = "0.8", optional = true }
http-body = "1"
http-body-util = "0.1"
hyper = { version = "1", features = ["http1", "client"] }
Expand Down
30 changes: 27 additions & 3 deletions src/async_impl/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ use std::net::SocketAddr;
use std::pin::Pin;

use bytes::Bytes;
use encoding_rs::{Encoding, UTF_8};
use http_body_util::BodyExt;
use hyper::{HeaderMap, StatusCode, Version};
use hyper_util::client::legacy::connect::HttpInfo;
use mime::Mime;
#[cfg(feature = "json")]
use serde::de::DeserializeOwned;
#[cfg(feature = "json")]
Expand All @@ -21,6 +19,11 @@ use crate::async_impl::body::ResponseBody;
#[cfg(feature = "cookies")]
use crate::cookie;

#[cfg(feature = "charset")]
use encoding_rs::{Encoding, UTF_8};
#[cfg(feature = "charset")]
use mime::Mime;

/// A Response to a submitted `Request`.
pub struct Response {
pub(super) res: hyper::Response<Decoder>,
Expand Down Expand Up @@ -135,6 +138,11 @@ impl Response {
///
/// Note that the BOM is stripped from the returned String.
///
/// # Note
///
/// If the `charset` feature is disabled the method will only attempt to decode the
/// response as UTF-8, regardless of the given `Content-Type`
///
/// # Example
///
/// ```
Expand All @@ -149,7 +157,17 @@ impl Response {
/// # }
/// ```
pub async fn text(self) -> crate::Result<String> {
self.text_with_charset("utf-8").await
#[cfg(feature = "charset")]
{
self.text_with_charset("utf-8").await
}

#[cfg(not(feature = "charset"))]
{
let full = self.bytes().await?;
let text = String::from_utf8_lossy(&full);
Ok(text.into_owned())
}
}

/// Get the full response text given a specific encoding.
Expand All @@ -164,6 +182,10 @@ impl Response {
///
/// [`encoding_rs`]: https://docs.rs/encoding_rs/0.8/encoding_rs/#relationship-with-windows-code-pages
///
/// # Optional
///
/// This requires the optional `encoding_rs` feature enabled.
///
/// # Example
///
/// ```
Expand All @@ -177,6 +199,8 @@ impl Response {
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "charset")]
#[cfg_attr(docsrs, doc(cfg(feature = "charset")))]
pub async fn text_with_charset(self, default_encoding: &str) -> crate::Result<String> {
let content_type = self
.headers()
Expand Down
16 changes: 15 additions & 1 deletion src/blocking/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ impl Response {
/// Encoding is determined from the `charset` parameter of `Content-Type` header,
/// and defaults to `utf-8` if not presented.
///
/// # Note
///
/// If the `charset` feature is disabled the method will only attempt to decode the
/// response as UTF-8, regardless of the given `Content-Type`
///
/// # Example
///
/// ```rust
Expand All @@ -280,7 +285,10 @@ impl Response {
/// # }
/// ```
pub fn text(self) -> crate::Result<String> {
self.text_with_charset("utf-8")
wait::timeout(self.inner.text(), self.timeout).map_err(|e| match e {
wait::Waited::TimedOut(e) => crate::error::decode(e),
wait::Waited::Inner(e) => e,
})
}

/// Get the response text given a specific encoding.
Expand All @@ -293,6 +301,10 @@ impl Response {
///
/// [`encoding_rs`]: https://docs.rs/encoding_rs/0.8/encoding_rs/#relationship-with-windows-code-pages
///
/// # Optional
///
/// This requires the optional `charset` feature enabled.
///
/// # Example
///
/// ```rust
Expand All @@ -303,6 +315,8 @@ impl Response {
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "charset")]
#[cfg_attr(docsrs, doc(cfg(feature = "charset")))]
pub fn text_with_charset(self, default_encoding: &str) -> crate::Result<String> {
wait::timeout(self.inner.text_with_charset(default_encoding), self.timeout).map_err(|e| {
match e {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
//! - **rustls-tls-native-roots**: Enables TLS functionality provided by `rustls`,
//! while using root certificates from the `rustls-native-certs` crate.
//! - **blocking**: Provides the [blocking][] client API.
//! - **charset** *(enabled by default)*: Improved support for decoding text.
//! - **cookies**: Provides cookie session support.
//! - **gzip**: Provides response body gzip decompression.
//! - **brotli**: Provides response body brotli decompression.
Expand Down
1 change: 1 addition & 0 deletions tests/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn test_response_text() {
}

#[test]
#[cfg(feature = "charset")]
fn test_response_non_utf_8_text() {
let server = server::http(move |_req| async {
http::Response::builder()
Expand Down

0 comments on commit 6c6170b

Please sign in to comment.