Skip to content

Add DisplayAsDebug - A struct to help with Debug impls #49067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
3 changes: 3 additions & 0 deletions src/liballoc/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ pub use core::fmt::{ArgumentV1, Arguments, write};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};

#[unstable(feature = "display_as_debug", issue = "49128")]
pub use core::fmt::DisplayAsDebug;

use string;

/// The `format` function takes an [`Arguments`] struct and returns the resulting
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(display_as_debug)]
#![feature(from_ref)]
#![feature(fundamental)]
#![feature(generic_param_attrs)]
Expand Down
67 changes: 67 additions & 0 deletions src/libcore/fmt/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,3 +537,70 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
self.fmt.alternate()
}
}

/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations.
///
/// This is useful you need to use the `Display` `impl` of a type in a `Debug`
/// context instead of the `Debug` `impl` of the type. One such scenario where
/// this is useful is when you need an unquoted string as part of your
/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. As seen
/// below in the example, this can happen when you want to use [`.debug_set()`]
/// methods and friends.
///
/// [`.debug_set()`]: struct.Formatter.html#method.debug_set
///
/// The difference between `&'a str` and `DisplayAsDebug<&'a str>` in a `Debug`
/// context such as `println!("{:?}", <value>)` is that the former will quote
/// the string while the latter will not. In other words, the following holds:
///
/// ```rust
/// #![feature(display_as_debug)]
/// use std::fmt::DisplayAsDebug;
///
/// assert_eq!("foo", format!("{:?}", DisplayAsDebug("foo")));
/// assert_eq!("\"foo\"", format!("{:?}", "foo"));
/// ```
///
/// # Examples
///
/// In this example we use `DisplayAsDebug("_")` for a "catch all" match arm.
///
/// ```rust
/// #![feature(display_as_debug)]
/// use std::fmt::{Debug, Formatter, DisplayAsDebug, Result};
///
/// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R));
/// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V);
///
/// impl<'a, L: 'a + Debug, R: 'a + Debug> Debug for Arm<'a, L, R> {
/// fn fmt(&self, fmt: &mut Formatter) -> Result {
/// L::fmt(&(self.0).0, fmt)?;
/// fmt.write_str(" => ")?;
/// R::fmt(&(self.0).1, fmt)
/// }
/// }
///
/// impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Table<'a, K, V> {
/// fn fmt(&self, fmt: &mut Formatter) -> Result {
/// fmt.debug_set()
/// .entries(self.0.iter().map(Arm))
/// .entry(&Arm(&(DisplayAsDebug("_"), &self.1)))
/// .finish()
/// }
/// }
///
/// let table = (1..3).enumerate().collect::<Vec<_>>();
/// assert_eq!(format!("{:?}", Table(&*table, 0)),
/// "{0 => 1, 1 => 2, _ => 0}");
/// ```
#[unstable(feature = "display_as_debug", issue = "49128")]
#[must_use]
#[derive(Copy, Clone)]
pub struct DisplayAsDebug<T>(pub T);

#[unstable(feature = "display_as_debug", issue = "49128")]
impl<T: fmt::Display> fmt::Debug for DisplayAsDebug<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
<T as fmt::Display>::fmt(&self.0, fmt)
}
}
3 changes: 3 additions & 0 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub enum Alignment {
#[stable(feature = "debug_builders", since = "1.2.0")]
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};

#[unstable(feature = "display_as_debug", issue = "49128")]
pub use self::builders::DisplayAsDebug;

#[unstable(feature = "fmt_internals", reason = "internal to format_args!",
issue = "0")]
#[doc(hidden)]
Expand Down