@@ -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 < F > ( & 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 < F > ( & 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 < 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) ;
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 < F > ( & 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 < 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
+ }
0 commit comments