Closure-consuming helper functions for fmt::Debug helpers · rust-lang/rust@82a9f94 (original) (raw)

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

`

130

130

```` /// ```


`131`

`131`

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

`

`132`

`132`

`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`

`+

{

`

`133`

`145`

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

`

`134`

`146`

`if self.is_pretty() {

`

`135`

`147`

`if !self.has_fields {

`

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

`

`140`

`152`

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

`

`141`

`153`

` writer.write_str(name)?;

`

`142`

`154`

` writer.write_str(": ")?;

`

`143`

``

`-

value.fmt(&mut writer)?;

`

``

`155`

`+

value_fmt(&mut writer)?;

`

`144`

`156`

` writer.write_str(",\n")

`

`145`

`157`

`} else {

`

`146`

`158`

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

`

`147`

`159`

`self.fmt.write_str(prefix)?;

`

`148`

`160`

`self.fmt.write_str(name)?;

`

`149`

`161`

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

`

`150`

``

`-

value.fmt(self.fmt)

`

``

`162`

`+

value_fmt(self.fmt)

`

`151`

`163`

`}

`

`152`

`164`

`});

`

`153`

`165`

``

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

`

`315`

`327`

```` /// ```

316

328

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

`

317

329

`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(&mut self, value_fmt: F) -> &mut Self

`

``

339

`+

where

`

``

340

`+

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

`

``

341

`+

{

`

318

342

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

`

319

343

`if self.is_pretty() {

`

320

344

`if self.fields == 0 {

`

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

`

323

347

`let mut slot = None;

`

324

348

`let mut state = Default::default();

`

325

349

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

`

326

``

`-

value.fmt(&mut writer)?;

`

``

350

`+

value_fmt(&mut writer)?;

`

327

351

` writer.write_str(",\n")

`

328

352

`} else {

`

329

353

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

`

330

354

`self.fmt.write_str(prefix)?;

`

331

``

`-

value.fmt(self.fmt)

`

``

355

`+

value_fmt(self.fmt)

`

332

356

`}

`

333

357

`});

`

334

358

``

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

`

385

409

`}

`

386

410

``

387

411

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

`

388

``

`-

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

`

``

412

`+

fn entry_with(&mut self, entry_fmt: F)

`

``

413

`+

where

`

``

414

`+

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

`

``

415

`+

{

`

389

416

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

`

390

417

`if self.is_pretty() {

`

391

418

`if !self.has_fields {

`

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

`

394

421

`let mut slot = None;

`

395

422

`let mut state = Default::default();

`

396

423

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

`

397

``

`-

entry.fmt(&mut writer)?;

`

``

424

`+

entry_fmt(&mut writer)?;

`

398

425

` writer.write_str(",\n")

`

399

426

`} else {

`

400

427

`if self.has_fields {

`

401

428

`self.fmt.write_str(", ")?

`

402

429

`}

`

403

``

`-

entry.fmt(self.fmt)

`

``

430

`+

entry_fmt(self.fmt)

`

404

431

`}

`

405

432

`});

`

406

433

``

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

`

475

502

```` /// ```


`476`

`503`

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

`

`477`

`504`

`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);

`

`479`

`519`

`self

`

`480`

`520`

`}

`

`481`

`521`

``

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

`

`605`

`645`

```` /// ```

606

646

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

`

607

647

`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(&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);

`

609

662

`self

`

610

663

`}

`

611

664

``

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

`

775

828

```` /// ```


`776`

`829`

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

`

`777`

`830`

`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`

`+

{

`

`778`

`843`

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

`

`779`

`844`

`assert!(

`

`780`

`845`

` !self.has_key,

`

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

`

`789`

`854`

`let mut slot = None;

`

`790`

`855`

`self.state = Default::default();

`

`791`

`856`

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

`

`792`

``

`-

key.fmt(&mut writer)?;

`

``

`857`

`+

key_fmt(&mut writer)?;

`

`793`

`858`

` writer.write_str(": ")?;

`

`794`

`859`

`} else {

`

`795`

`860`

`if self.has_fields {

`

`796`

`861`

`self.fmt.write_str(", ")?

`

`797`

`862`

`}

`

`798`

``

`-

key.fmt(self.fmt)?;

`

``

`863`

`+

key_fmt(self.fmt)?;

`

`799`

`864`

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

`

`800`

`865`

`}

`

`801`

`866`

``

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

`

`839`

`904`

```` /// ```

840

905

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

`

841

906

`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(&mut self, value_fmt: F) -> &mut Self

`

``

916

`+

where

`

``

917

`+

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

`

``

918

`+

{

`

842

919

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

`

843

920

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

`

844

921

``

845

922

`if self.is_pretty() {

`

846

923

`let mut slot = None;

`

847

924

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

`

848

``

`-

value.fmt(&mut writer)?;

`

``

925

`+

value_fmt(&mut writer)?;

`

849

926

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

`

850

927

`} else {

`

851

``

`-

value.fmt(self.fmt)?;

`

``

928

`+

value_fmt(self.fmt)?;

`

852

929

`}

`

853

930

``

854

931

`self.has_key = false;

`

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

`

936

1013

`self.fmt.alternate()

`

937

1014

`}

`

938

1015

`}

`

``

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(pub F)

`

``

1035

`+

where

`

``

1036

`+

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

`

``

1037

+

``

1038

`+

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

`

``

1039

`+

impl fmt::Debug for FormatterFn

`

``

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 fmt::Display for FormatterFn

`

``

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

`+

}

`