Rollup merge of #117730 - jmillikin:fmt-debug-helper-fns, r=cuviper · rust-lang/rust@0f1da7e

@@ -130,6 +130,18 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {

130130

/// ```

131131

#[stable(feature = "debug_builders", since = "1.2.0")]

132132

pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut Self {

133+

self.field_with(name, |f| value.fmt(f))

134+

}

135+136+

/// Adds a new field to the generated struct output.

137+

///

138+

/// This method is equivalent to [`DebugStruct::field`], but formats the

139+

/// value using a provided closure rather than by calling [`Debug::fmt`].

140+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

141+

pub fn field_with<F>(&mut self, name: &str, value_fmt: F) -> &mut Self

142+

where

143+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

144+

{

133145

self.result = self.result.and_then(|_| {

134146

if self.is_pretty() {

135147

if !self.has_fields {

@@ -140,14 +152,14 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {

140152

let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);

141153

writer.write_str(name)?;

142154

writer.write_str(": ")?;

143-

value.fmt(&mut writer)?;

155+

value_fmt(&mut writer)?;

144156

writer.write_str(",\n")

145157

} else {

146158

let prefix = if self.has_fields { ", " } else { " { " };

147159

self.fmt.write_str(prefix)?;

148160

self.fmt.write_str(name)?;

149161

self.fmt.write_str(": ")?;

150-

value.fmt(self.fmt)

162+

value_fmt(self.fmt)

151163

}

152164

});

153165

@@ -315,6 +327,18 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {

315327

/// ```

316328

#[stable(feature = "debug_builders", since = "1.2.0")]

317329

pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut Self {

330+

self.field_with(|f| value.fmt(f))

331+

}

332+333+

/// Adds a new field to the generated tuple struct output.

334+

///

335+

/// This method is equivalent to [`DebugTuple::field`], but formats the

336+

/// value using a provided closure rather than by calling [`Debug::fmt`].

337+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

338+

pub fn field_with<F>(&mut self, value_fmt: F) -> &mut Self

339+

where

340+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

341+

{

318342

self.result = self.result.and_then(|_| {

319343

if self.is_pretty() {

320344

if self.fields == 0 {

@@ -323,12 +347,12 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {

323347

let mut slot = None;

324348

let mut state = Default::default();

325349

let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);

326-

value.fmt(&mut writer)?;

350+

value_fmt(&mut writer)?;

327351

writer.write_str(",\n")

328352

} else {

329353

let prefix = if self.fields == 0 { "(" } else { ", " };

330354

self.fmt.write_str(prefix)?;

331-

value.fmt(self.fmt)

355+

value_fmt(self.fmt)

332356

}

333357

});

334358

@@ -385,7 +409,10 @@ struct DebugInner<'a, 'b: 'a> {

385409

}

386410387411

impl<'a, 'b: 'a> DebugInner<'a, 'b> {

388-

fn entry(&mut self, entry: &dyn fmt::Debug) {

412+

fn entry_with<F>(&mut self, entry_fmt: F)

413+

where

414+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

415+

{

389416

self.result = self.result.and_then(|_| {

390417

if self.is_pretty() {

391418

if !self.has_fields {

@@ -394,13 +421,13 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {

394421

let mut slot = None;

395422

let mut state = Default::default();

396423

let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut state);

397-

entry.fmt(&mut writer)?;

424+

entry_fmt(&mut writer)?;

398425

writer.write_str(",\n")

399426

} else {

400427

if self.has_fields {

401428

self.fmt.write_str(", ")?

402429

}

403-

entry.fmt(self.fmt)

430+

entry_fmt(self.fmt)

404431

}

405432

});

406433

@@ -475,7 +502,20 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {

475502

/// ```

476503

#[stable(feature = "debug_builders", since = "1.2.0")]

477504

pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {

478-

self.inner.entry(entry);

505+

self.inner.entry_with(|f| entry.fmt(f));

506+

self

507+

}

508+509+

/// Adds a new entry to the set output.

510+

///

511+

/// This method is equivalent to [`DebugSet::entry`], but formats the

512+

/// entry using a provided closure rather than by calling [`Debug::fmt`].

513+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

514+

pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self

515+

where

516+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

517+

{

518+

self.inner.entry_with(entry_fmt);

479519

self

480520

}

481521

@@ -605,7 +645,20 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> {

605645

/// ```

606646

#[stable(feature = "debug_builders", since = "1.2.0")]

607647

pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut Self {

608-

self.inner.entry(entry);

648+

self.inner.entry_with(|f| entry.fmt(f));

649+

self

650+

}

651+652+

/// Adds a new entry to the list output.

653+

///

654+

/// This method is equivalent to [`DebugList::entry`], but formats the

655+

/// entry using a provided closure rather than by calling [`Debug::fmt`].

656+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

657+

pub fn entry_with<F>(&mut self, entry_fmt: F) -> &mut Self

658+

where

659+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

660+

{

661+

self.inner.entry_with(entry_fmt);

609662

self

610663

}

611664

@@ -775,6 +828,18 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {

775828

/// ```

776829

#[stable(feature = "debug_map_key_value", since = "1.42.0")]

777830

pub fn key(&mut self, key: &dyn fmt::Debug) -> &mut Self {

831+

self.key_with(|f| key.fmt(f))

832+

}

833+834+

/// Adds the key part of a new entry to the map output.

835+

///

836+

/// This method is equivalent to [`DebugMap::key`], but formats the

837+

/// key using a provided closure rather than by calling [`Debug::fmt`].

838+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

839+

pub fn key_with<F>(&mut self, key_fmt: F) -> &mut Self

840+

where

841+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

842+

{

778843

self.result = self.result.and_then(|_| {

779844

assert!(

780845

!self.has_key,

@@ -789,13 +854,13 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {

789854

let mut slot = None;

790855

self.state = Default::default();

791856

let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);

792-

key.fmt(&mut writer)?;

857+

key_fmt(&mut writer)?;

793858

writer.write_str(": ")?;

794859

} else {

795860

if self.has_fields {

796861

self.fmt.write_str(", ")?

797862

}

798-

key.fmt(self.fmt)?;

863+

key_fmt(self.fmt)?;

799864

self.fmt.write_str(": ")?;

800865

}

801866

@@ -839,16 +904,28 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {

839904

/// ```

840905

#[stable(feature = "debug_map_key_value", since = "1.42.0")]

841906

pub fn value(&mut self, value: &dyn fmt::Debug) -> &mut Self {

907+

self.value_with(|f| value.fmt(f))

908+

}

909+910+

/// Adds the value part of a new entry to the map output.

911+

///

912+

/// This method is equivalent to [`DebugMap::value`], but formats the

913+

/// value using a provided closure rather than by calling [`Debug::fmt`].

914+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

915+

pub fn value_with<F>(&mut self, value_fmt: F) -> &mut Self

916+

where

917+

F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,

918+

{

842919

self.result = self.result.and_then(|_| {

843920

assert!(self.has_key, "attempted to format a map value before its key");

844921845922

if self.is_pretty() {

846923

let mut slot = None;

847924

let mut writer = PadAdapter::wrap(self.fmt, &mut slot, &mut self.state);

848-

value.fmt(&mut writer)?;

925+

value_fmt(&mut writer)?;

849926

writer.write_str(",\n")?;

850927

} else {

851-

value.fmt(self.fmt)?;

928+

value_fmt(self.fmt)?;

852929

}

853930854931

self.has_key = false;

@@ -936,3 +1013,44 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {

9361013

self.fmt.alternate()

9371014

}

9381015

}

1016+1017+

/// Implements [`fmt::Debug`] and [`fmt::Display`] using a function.

1018+

///

1019+

/// # Examples

1020+

///

1021+

/// ```

1022+

/// #![feature(debug_closure_helpers)]

1023+

/// use std::fmt;

1024+

///

1025+

/// let value = 'a';

1026+

/// assert_eq!(format!("{}", value), "a");

1027+

/// assert_eq!(format!("{:?}", value), "'a'");

1028+

///

1029+

/// let wrapped = fmt::FormatterFn(|f| write!(f, "{:?}", &value));

1030+

/// assert_eq!(format!("{}", wrapped), "'a'");

1031+

/// assert_eq!(format!("{:?}", wrapped), "'a'");

1032+

/// ```

1033+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

1034+

pub struct FormatterFn<F>(pub F)

1035+

where

1036+

F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;

1037+1038+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

1039+

impl<F> fmt::Debug for FormatterFn<F>

1040+

where

1041+

F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,

1042+

{

1043+

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

1044+

(self.0)(f)

1045+

}

1046+

}

1047+1048+

#[unstable(feature = "debug_closure_helpers", issue = "117729")]

1049+

impl<F> fmt::Display for FormatterFn<F>

1050+

where

1051+

F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,

1052+

{

1053+

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

1054+

(self.0)(f)

1055+

}

1056+

}