Improve fmt::Debug of Client and ClientBuilder

This commit is contained in:
Sean McArthur
2019-10-09 12:15:27 -07:00
parent 75ee4646ac
commit 6b5726aaa8
5 changed files with 141 additions and 16 deletions

View File

@@ -12,7 +12,6 @@ use http::header::{
}; };
use http::Uri; use http::Uri;
use hyper::client::ResponseFuture; use hyper::client::ResponseFuture;
use mime;
#[cfg(feature = "default-tls")] #[cfg(feature = "default-tls")]
use native_tls::TlsConnector; use native_tls::TlsConnector;
use std::future::Future; use std::future::Future;
@@ -58,6 +57,7 @@ pub struct ClientBuilder {
} }
struct Config { struct Config {
// NOTE: When adding a new field, update `fmt::Debug for ClientBuilder`
gzip: bool, gzip: bool,
headers: HeaderMap, headers: HeaderMap,
#[cfg(feature = "default-tls")] #[cfg(feature = "default-tls")]
@@ -91,10 +91,7 @@ impl ClientBuilder {
pub fn new() -> ClientBuilder { pub fn new() -> ClientBuilder {
let mut headers: HeaderMap<HeaderValue> = HeaderMap::with_capacity(2); let mut headers: HeaderMap<HeaderValue> = HeaderMap::with_capacity(2);
headers.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT)); headers.insert(USER_AGENT, HeaderValue::from_static(DEFAULT_USER_AGENT));
headers.insert( headers.insert(ACCEPT, HeaderValue::from_static("*/*"));
ACCEPT,
HeaderValue::from_str(mime::STAR_STAR.as_ref()).expect("unable to parse mime"),
);
ClientBuilder { ClientBuilder {
config: Config { config: Config {
@@ -567,8 +564,6 @@ impl ClientBuilder {
self.config.tls = TlsBackend::Rustls; self.config.tls = TlsBackend::Rustls;
self self
} }
} }
type HyperClient = hyper::Client<Connector, super::body::ImplStream>; type HyperClient = hyper::Client<Connector, super::body::ImplStream>;
@@ -781,17 +776,90 @@ impl Client {
impl fmt::Debug for Client { impl fmt::Debug for Client {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Client") let mut builder = f.debug_struct("ClientBuilder");
.field("gzip", &self.inner.gzip) self.inner.fmt_fields(&mut builder);
.field("redirect_policy", &self.inner.redirect_policy) builder.finish()
.field("referer", &self.inner.referer)
.finish()
} }
} }
impl fmt::Debug for ClientBuilder { impl fmt::Debug for ClientBuilder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ClientBuilder").finish() let mut builder = f.debug_struct("ClientBuilder");
self.config.fmt_fields(&mut builder);
builder.finish()
}
}
impl Config {
fn fmt_fields(&self, f: &mut fmt::DebugStruct<'_, '_>) {
// Instead of deriving Debug, only print fields when their output
// would provide relevant or interesting data.
#[cfg(feature = "cookies")]
{
if let Some(_) = self.cookie_store {
f.field("cookie_store", &true);
}
}
f.field("gzip", &self.gzip);
if !self.proxies.is_empty() {
f.field("proxies", &self.proxies);
}
if !self.redirect_policy.is_default() {
f.field("redirect_policy", &self.redirect_policy);
}
if self.referer {
f.field("referer", &true);
}
f.field("default_headers", &self.headers);
if self.http1_title_case_headers {
f.field("http1_title_case_headers", &true);
}
if self.http2_only {
f.field("http2_prior_knowledge", &true);
}
if let Some(ref d) = self.connect_timeout {
f.field("connect_timeout", d);
}
if let Some(ref d) = self.timeout {
f.field("timeout", d);
}
if let Some(ref v) = self.local_address {
f.field("local_address", v);
}
if self.nodelay {
f.field("tcp_nodelay", &true);
}
#[cfg(feature = "default-tls")]
{
if !self.hostname_verification {
f.field("danger_accept_invalid_hostnames", &true);
}
}
#[cfg(feature = "tls")]
{
if !self.certs_verification {
f.field("danger_accept_invalid_certs", &true);
}
}
#[cfg(all(feature = "default-tls", feature = "rustls-tls"))]
{
f.field("tls_backend", &self.tls);
}
} }
} }
@@ -808,6 +876,43 @@ struct ClientRef {
proxies_maybe_http_auth: bool, proxies_maybe_http_auth: bool,
} }
impl ClientRef {
fn fmt_fields(&self, f: &mut fmt::DebugStruct<'_, '_>) {
// Instead of deriving Debug, only print fields when their output
// would provide relevant or interesting data.
#[cfg(feature = "cookies")]
{
if let Some(_) = self.cookie_store {
f.field("cookie_store", &true);
}
}
f.field("gzip", &self.gzip);
if !self.proxies.is_empty() {
f.field("proxies", &self.proxies);
}
if !self.redirect_policy.is_default() {
f.field("redirect_policy", &self.redirect_policy);
}
if self.referer {
f.field("referer", &true);
}
f.field("default_headers", &self.headers);
if let Some(ref d) = self.request_timeout {
f.field("timeout", d);
}
}
}
pub(super) struct Pending { pub(super) struct Pending {
inner: PendingInner, inner: PendingInner,
} }

View File

@@ -538,7 +538,7 @@ impl fmt::Debug for Client {
impl fmt::Debug for ClientBuilder { impl fmt::Debug for ClientBuilder {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ClientBuilder").finish() self.inner.fmt(f)
} }
} }

View File

@@ -48,7 +48,7 @@ use winreg::RegKey;
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[derive(Clone, Debug)] #[derive(Clone)]
pub struct Proxy { pub struct Proxy {
intercept: Intercept, intercept: Intercept,
} }
@@ -262,6 +262,12 @@ impl Proxy {
} }
} }
impl fmt::Debug for Proxy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Proxy").field(&self.intercept).finish()
}
}
impl ProxyScheme { impl ProxyScheme {
// To start conservative, keep builders private for now. // To start conservative, keep builders private for now.

View File

@@ -14,7 +14,6 @@ use crate::Url;
/// the allowed maximum redirect hops in a chain. /// the allowed maximum redirect hops in a chain.
/// - `none` can be used to disable all redirect behavior. /// - `none` can be used to disable all redirect behavior.
/// - `custom` can be used to create a customized policy. /// - `custom` can be used to create a customized policy.
#[derive(Debug)]
pub struct RedirectPolicy { pub struct RedirectPolicy {
inner: Policy, inner: Policy,
} }
@@ -142,10 +141,18 @@ impl RedirectPolicy {
}) })
.inner .inner
} }
pub(crate) fn is_default(&self) -> bool {
match self.inner {
Policy::Limit(10) => true,
_ => false,
}
}
} }
impl Default for RedirectPolicy { impl Default for RedirectPolicy {
fn default() -> RedirectPolicy { fn default() -> RedirectPolicy {
// Keep `is_default` in sync
RedirectPolicy::limited(10) RedirectPolicy::limited(10)
} }
} }
@@ -206,6 +213,12 @@ enum Policy {
None, None,
} }
impl fmt::Debug for RedirectPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("RedirectPolicy").field(&self.inner).finish()
}
}
impl fmt::Debug for Policy { impl fmt::Debug for Policy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {

View File

@@ -254,6 +254,7 @@ impl fmt::Debug for Identity {
} }
} }
#[derive(Debug)]
pub(crate) enum TlsBackend { pub(crate) enum TlsBackend {
#[cfg(feature = "default-tls")] #[cfg(feature = "default-tls")]
Default, Default,