mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Closure-consuming helper functions for fmt::Debug
helpers
This commit is contained in:
parent
90fdc1fc27
commit
82a9f94de5
@ -555,6 +555,8 @@
|
||||
pub use core::fmt::Alignment;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::fmt::Error;
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub use core::fmt::FormatterFn;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::fmt::{write, Arguments};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -130,6 +130,18 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self {
|
||||
self.field_with(name, |f| value.fmt(f))
|
||||
}
|
||||
|
||||
/// Adds a new field to the generated struct output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugStruct::field`], but formats the
|
||||
/// value using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.result = self.result.and_then(|_| {
|
||||
if self.is_pretty() {
|
||||
if !self.has_fields {
|
||||
@ -140,14 +152,14 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
|
||||
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
|
||||
writer.write_str(name)?;
|
||||
writer.write_str(": ")?;
|
||||
value.fmt(&mut writer)?;
|
||||
value_fmt(&mut writer)?;
|
||||
writer.write_str(",\n")
|
||||
} else {
|
||||
let prefix = if self.has_fields { ", " } else { " { " };
|
||||
self.fmt.write_str(prefix)?;
|
||||
self.fmt.write_str(name)?;
|
||||
self.fmt.write_str(": ")?;
|
||||
value.fmt(self.fmt)
|
||||
value_fmt(self.fmt)
|
||||
}
|
||||
});
|
||||
|
||||
@ -315,6 +327,18 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {
|
||||
self.field_with(|f| value.fmt(f))
|
||||
}
|
||||
|
||||
/// Adds a new field to the generated tuple struct output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugTuple::field`], but formats the
|
||||
/// value using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.result = self.result.and_then(|_| {
|
||||
if self.is_pretty() {
|
||||
if self.fields == 0 {
|
||||
@ -323,12 +347,12 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
|
||||
let mut slot = None;
|
||||
let mut state = Default::default();
|
||||
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
|
||||
value.fmt(&mut writer)?;
|
||||
value_fmt(&mut writer)?;
|
||||
writer.write_str(",\n")
|
||||
} else {
|
||||
let prefix = if self.fields == 0 { "(" } else { ", " };
|
||||
self.fmt.write_str(prefix)?;
|
||||
value.fmt(self.fmt)
|
||||
value_fmt(self.fmt)
|
||||
}
|
||||
});
|
||||
|
||||
@ -385,7 +409,10 @@ struct DebugInner<'a, 'b: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a> DebugInner<'a, 'b> {
|
||||
fn entry(&mut self, entry: &dyn fmt::Debug) {
|
||||
fn entry_with<F>(&mut self, entry_fmt: F)
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.result = self.result.and_then(|_| {
|
||||
if self.is_pretty() {
|
||||
if !self.has_fields {
|
||||
@ -394,13 +421,13 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
|
||||
let mut slot = None;
|
||||
let mut state = Default::default();
|
||||
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);
|
||||
entry.fmt(&mut writer)?;
|
||||
entry_fmt(&mut writer)?;
|
||||
writer.write_str(",\n")
|
||||
} else {
|
||||
if self.has_fields {
|
||||
self.fmt.write_str(", ")?
|
||||
}
|
||||
entry.fmt(self.fmt)
|
||||
entry_fmt(self.fmt)
|
||||
}
|
||||
});
|
||||
|
||||
@ -475,7 +502,20 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
|
||||
self.inner.entry(entry);
|
||||
self.inner.entry_with(|f| entry.fmt(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a new entry to the set output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugSet::entry`], but formats the
|
||||
/// entry using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.inner.entry_with(entry_fmt);
|
||||
self
|
||||
}
|
||||
|
||||
@ -605,7 +645,20 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {
|
||||
self.inner.entry(entry);
|
||||
self.inner.entry_with(|f| entry.fmt(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a new entry to the list output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugList::entry`], but formats the
|
||||
/// entry using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.inner.entry_with(entry_fmt);
|
||||
self
|
||||
}
|
||||
|
||||
@ -775,6 +828,18 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
|
||||
pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {
|
||||
self.key_with(|f| key.fmt(f))
|
||||
}
|
||||
|
||||
/// Adds the key part of a new entry to the map output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugMap::key`], but formats the
|
||||
/// key using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.result = self.result.and_then(|_| {
|
||||
assert!(
|
||||
!self.has_key,
|
||||
@ -789,13 +854,13 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
||||
let mut slot = None;
|
||||
self.state = Default::default();
|
||||
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
|
||||
key.fmt(&mut writer)?;
|
||||
key_fmt(&mut writer)?;
|
||||
writer.write_str(": ")?;
|
||||
} else {
|
||||
if self.has_fields {
|
||||
self.fmt.write_str(", ")?
|
||||
}
|
||||
key.fmt(self.fmt)?;
|
||||
key_fmt(self.fmt)?;
|
||||
self.fmt.write_str(": ")?;
|
||||
}
|
||||
|
||||
@ -839,16 +904,28 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
||||
/// ```
|
||||
#[stable(feature = "debug_map_key_value", since = "1.42.0")]
|
||||
pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {
|
||||
self.value_with(|f| value.fmt(f))
|
||||
}
|
||||
|
||||
/// Adds the value part of a new entry to the map output.
|
||||
///
|
||||
/// This method is equivalent to [`DebugMap::value`], but formats the
|
||||
/// value using a provided closure rather than by calling [`Debug::fmt`].
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self
|
||||
where
|
||||
F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
self.result = self.result.and_then(|_| {
|
||||
assert!(self.has_key, "attempted to format a map value before its key");
|
||||
|
||||
if self.is_pretty() {
|
||||
let mut slot = None;
|
||||
let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);
|
||||
value.fmt(&mut writer)?;
|
||||
value_fmt(&mut writer)?;
|
||||
writer.write_str(",\n")?;
|
||||
} else {
|
||||
value.fmt(self.fmt)?;
|
||||
value_fmt(self.fmt)?;
|
||||
}
|
||||
|
||||
self.has_key = false;
|
||||
@ -936,3 +1013,44 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
||||
self.fmt.alternate()
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements [`fmt::Debug`] and [`fmt::Display`] using a function.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(debug_closure_helpers)]
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// let value = 'a';
|
||||
/// assert_eq!(format!("{}", value), "a");
|
||||
/// assert_eq!(format!("{:?}", value), "'a'");
|
||||
///
|
||||
/// let wrapped = fmt::FormatterFn(|f| write!(f, "{:?}", &value));
|
||||
/// assert_eq!(format!("{}", wrapped), "'a'");
|
||||
/// assert_eq!(format!("{:?}", wrapped), "'a'");
|
||||
/// ```
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub struct FormatterFn<F>(pub F)
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;
|
||||
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
impl<F> fmt::Debug for FormatterFn<F>
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
(self.0)(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
impl<F> fmt::Display for FormatterFn<F>
|
||||
where
|
||||
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
(self.0)(f)
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,9 @@ pub enum Alignment {
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
|
||||
|
||||
#[unstable(feature = "debug_closure_helpers", issue = "117729")]
|
||||
pub use self::builders::FormatterFn;
|
||||
|
||||
/// The type returned by formatter methods.
|
||||
///
|
||||
/// # Examples
|
||||
|
Loading…
Reference in New Issue
Block a user