11use crate :: fmt;
22
3- struct PadAdapter < ' a > {
4- buf : & ' a mut ( dyn fmt:: Write + ' a ) ,
3+ struct PadAdapter < ' buf , ' state > {
4+ buf : & ' buf mut ( dyn fmt:: Write + ' buf ) ,
5+ state : & ' state mut PadAdapterState ,
6+ }
7+
8+ struct PadAdapterState {
59 on_newline : bool ,
610}
711
8- impl < ' a > PadAdapter < ' a > {
9- fn wrap < ' b , ' c : ' a +' b > ( fmt : & ' c mut fmt:: Formatter < ' _ > , slot : & ' b mut Option < Self > )
10- -> fmt:: Formatter < ' b > {
12+ impl Default for PadAdapterState {
13+ fn default ( ) -> Self {
14+ PadAdapterState {
15+ on_newline : true ,
16+ }
17+ }
18+ }
19+
20+ impl < ' buf , ' state > PadAdapter < ' buf , ' state > {
21+ fn wrap < ' slot , ' fmt : ' buf +' slot > ( fmt : & ' fmt mut fmt:: Formatter < ' _ > ,
22+ slot : & ' slot mut Option < Self > ,
23+ state : & ' state mut PadAdapterState ) -> fmt:: Formatter < ' slot > {
1124 fmt. wrap_buf ( move |buf| {
1225 * slot = Some ( PadAdapter {
1326 buf,
14- on_newline : true ,
27+ state ,
1528 } ) ;
1629 slot. as_mut ( ) . unwrap ( )
1730 } )
1831 }
1932}
2033
21- impl fmt:: Write for PadAdapter < ' _ > {
34+ impl fmt:: Write for PadAdapter < ' _ , ' _ > {
2235 fn write_str ( & mut self , mut s : & str ) -> fmt:: Result {
2336 while !s. is_empty ( ) {
24- if self . on_newline {
37+ if self . state . on_newline {
2538 self . buf . write_str ( " " ) ?;
2639 }
2740
2841 let split = match s. find ( '\n' ) {
2942 Some ( pos) => {
30- self . on_newline = true ;
43+ self . state . on_newline = true ;
3144 pos + 1
3245 }
3346 None => {
34- self . on_newline = false ;
47+ self . state . on_newline = false ;
3548 s. len ( )
3649 }
3750 } ;
@@ -133,7 +146,8 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
133146 self . fmt . write_str ( " {\n " ) ?;
134147 }
135148 let mut slot = None ;
136- let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot) ;
149+ let mut state = Default :: default ( ) ;
150+ let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot, & mut state) ;
137151 writer. write_str ( name) ?;
138152 writer. write_str ( ": " ) ?;
139153 value. fmt ( & mut writer) ?;
@@ -279,7 +293,8 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
279293 self . fmt . write_str ( "(\n " ) ?;
280294 }
281295 let mut slot = None ;
282- let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot) ;
296+ let mut state = Default :: default ( ) ;
297+ let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot, & mut state) ;
283298 value. fmt ( & mut writer) ?;
284299 writer. write_str ( ",\n " )
285300 } else {
@@ -349,7 +364,8 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
349364 self . fmt . write_str ( "\n " ) ?;
350365 }
351366 let mut slot = None ;
352- let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot) ;
367+ let mut state = Default :: default ( ) ;
368+ let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot, & mut state) ;
353369 entry. fmt ( & mut writer) ?;
354370 writer. write_str ( ",\n " )
355371 } else {
@@ -676,6 +692,9 @@ pub struct DebugMap<'a, 'b: 'a> {
676692 fmt : & ' a mut fmt:: Formatter < ' b > ,
677693 result : fmt:: Result ,
678694 has_fields : bool ,
695+ has_key : bool ,
696+ // The state of newlines is tracked between keys and values
697+ state : PadAdapterState ,
679698}
680699
681700pub fn debug_map_new < ' a , ' b > ( fmt : & ' a mut fmt:: Formatter < ' b > ) -> DebugMap < ' a , ' b > {
@@ -684,6 +703,8 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b
684703 fmt,
685704 result,
686705 has_fields : false ,
706+ has_key : false ,
707+ state : Default :: default ( ) ,
687708 }
688709}
689710
@@ -712,25 +733,123 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
712733 /// ```
713734 #[ stable( feature = "debug_builders" , since = "1.2.0" ) ]
714735 pub fn entry ( & mut self , key : & dyn fmt:: Debug , value : & dyn fmt:: Debug ) -> & mut DebugMap < ' a , ' b > {
736+ self . key ( key) . value ( value)
737+ }
738+
739+ /// Adds the key part of a new entry to the map output.
740+ ///
741+ /// This method, together with `value`, is an alternative to `entry` that
742+ /// can be used when the complete entry isn't known upfront. Prefer the `entry`
743+ /// method when it's possible to use.
744+ ///
745+ /// # Panics
746+ ///
747+ /// `key` must be called before `value` and each call to `key` must be followed
748+ /// by a corresponding call to `value`. Otherwise this method will panic.
749+ ///
750+ /// # Examples
751+ ///
752+ /// ```
753+ /// # #![feature(debug_map_key_value)]
754+ /// use std::fmt;
755+ ///
756+ /// struct Foo(Vec<(String, i32)>);
757+ ///
758+ /// impl fmt::Debug for Foo {
759+ /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
760+ /// fmt.debug_map()
761+ /// .key(&"whole").value(&self.0) // We add the "whole" entry.
762+ /// .finish()
763+ /// }
764+ /// }
765+ ///
766+ /// assert_eq!(
767+ /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
768+ /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
769+ /// );
770+ /// ```
771+ #[ unstable( feature = "debug_map_key_value" ,
772+ reason = "recently added" ,
773+ issue = "62482" ) ]
774+ pub fn key ( & mut self , key : & dyn fmt:: Debug ) -> & mut DebugMap < ' a , ' b > {
775+ assert ! ( !self . has_key, "attempted to begin a new map entry \
776+ without completing the previous one") ;
777+
715778 self . result = self . result . and_then ( |_| {
716779 if self . is_pretty ( ) {
717780 if !self . has_fields {
718781 self . fmt . write_str ( "\n " ) ?;
719782 }
720783 let mut slot = None ;
721- let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot) ;
784+ self . state = Default :: default ( ) ;
785+ let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot, & mut self . state ) ;
722786 key. fmt ( & mut writer) ?;
723787 writer. write_str ( ": " ) ?;
724- value. fmt ( & mut writer) ?;
725- writer. write_str ( ",\n " )
726788 } else {
727789 if self . has_fields {
728790 self . fmt . write_str ( ", " ) ?
729791 }
730792 key. fmt ( self . fmt ) ?;
731793 self . fmt . write_str ( ": " ) ?;
732- value. fmt ( self . fmt )
733794 }
795+
796+ self . has_key = true ;
797+ Ok ( ( ) )
798+ } ) ;
799+
800+ self
801+ }
802+
803+ /// Adds the value part of a new entry to the map output.
804+ ///
805+ /// This method, together with `key`, is an alternative to `entry` that
806+ /// can be used when the complete entry isn't known upfront. Prefer the `entry`
807+ /// method when it's possible to use.
808+ ///
809+ /// # Panics
810+ ///
811+ /// `key` must be called before `value` and each call to `key` must be followed
812+ /// by a corresponding call to `value`. Otherwise this method will panic.
813+ ///
814+ /// # Examples
815+ ///
816+ /// ```
817+ /// # #![feature(debug_map_key_value)]
818+ /// use std::fmt;
819+ ///
820+ /// struct Foo(Vec<(String, i32)>);
821+ ///
822+ /// impl fmt::Debug for Foo {
823+ /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
824+ /// fmt.debug_map()
825+ /// .key(&"whole").value(&self.0) // We add the "whole" entry.
826+ /// .finish()
827+ /// }
828+ /// }
829+ ///
830+ /// assert_eq!(
831+ /// format!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)])),
832+ /// "{\"whole\": [(\"A\", 10), (\"B\", 11)]}",
833+ /// );
834+ /// ```
835+ #[ unstable( feature = "debug_map_key_value" ,
836+ reason = "recently added" ,
837+ issue = "62482" ) ]
838+ pub fn value ( & mut self , value : & dyn fmt:: Debug ) -> & mut DebugMap < ' a , ' b > {
839+ assert ! ( self . has_key, "attempted to format a map value before its key" ) ;
840+
841+ self . result = self . result . and_then ( |_| {
842+ if self . is_pretty ( ) {
843+ let mut slot = None ;
844+ let mut writer = PadAdapter :: wrap ( & mut self . fmt , & mut slot, & mut self . state ) ;
845+ value. fmt ( & mut writer) ?;
846+ writer. write_str ( ",\n " ) ?;
847+ } else {
848+ value. fmt ( self . fmt ) ?;
849+ }
850+
851+ self . has_key = false ;
852+ Ok ( ( ) )
734853 } ) ;
735854
736855 self . has_fields = true ;
@@ -775,6 +894,11 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
775894
776895 /// Finishes output and returns any error encountered.
777896 ///
897+ /// # Panics
898+ ///
899+ /// `key` must be called before `value` and each call to `key` must be followed
900+ /// by a corresponding call to `value`. Otherwise this method will panic.
901+ ///
778902 /// # Examples
779903 ///
780904 /// ```
@@ -797,6 +921,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
797921 /// ```
798922 #[ stable( feature = "debug_builders" , since = "1.2.0" ) ]
799923 pub fn finish ( & mut self ) -> fmt:: Result {
924+ assert ! ( !self . has_key, "attempted to finish a map with a partial entry" ) ;
925+
800926 self . result . and_then ( |_| self . fmt . write_str ( "}" ) )
801927 }
802928
0 commit comments