@@ -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}
386410
387411impl < ' 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" ) ;
844921
845922 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 }
853930
854931 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+ }
0 commit comments