1
1
use crate :: fmt;
2
2
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 {
5
9
on_newline : bool ,
6
10
}
7
11
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 > {
11
24
fmt. wrap_buf ( move |buf| {
12
25
* slot = Some ( PadAdapter {
13
26
buf,
14
- on_newline : true ,
27
+ state ,
15
28
} ) ;
16
29
slot. as_mut ( ) . unwrap ( )
17
30
} )
18
31
}
19
32
}
20
33
21
- impl fmt:: Write for PadAdapter < ' _ > {
34
+ impl fmt:: Write for PadAdapter < ' _ , ' _ > {
22
35
fn write_str ( & mut self , mut s : & str ) -> fmt:: Result {
23
36
while !s. is_empty ( ) {
24
- if self . on_newline {
37
+ if self . state . on_newline {
25
38
self . buf . write_str ( " " ) ?;
26
39
}
27
40
28
41
let split = match s. find ( '\n' ) {
29
42
Some ( pos) => {
30
- self . on_newline = true ;
43
+ self . state . on_newline = true ;
31
44
pos + 1
32
45
}
33
46
None => {
34
- self . on_newline = false ;
47
+ self . state . on_newline = false ;
35
48
s. len ( )
36
49
}
37
50
} ;
@@ -133,7 +146,8 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
133
146
self . fmt . write_str ( " {\n " ) ?;
134
147
}
135
148
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) ;
137
151
writer. write_str ( name) ?;
138
152
writer. write_str ( ": " ) ?;
139
153
value. fmt ( & mut writer) ?;
@@ -279,7 +293,8 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
279
293
self . fmt . write_str ( "(\n " ) ?;
280
294
}
281
295
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) ;
283
298
value. fmt ( & mut writer) ?;
284
299
writer. write_str ( ",\n " )
285
300
} else {
@@ -349,7 +364,8 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
349
364
self . fmt . write_str ( "\n " ) ?;
350
365
}
351
366
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) ;
353
369
entry. fmt ( & mut writer) ?;
354
370
writer. write_str ( ",\n " )
355
371
} else {
@@ -676,6 +692,9 @@ pub struct DebugMap<'a, 'b: 'a> {
676
692
fmt : & ' a mut fmt:: Formatter < ' b > ,
677
693
result : fmt:: Result ,
678
694
has_fields : bool ,
695
+ has_key : bool ,
696
+ // The state of newlines is tracked between keys and values
697
+ state : PadAdapterState ,
679
698
}
680
699
681
700
pub 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
684
703
fmt,
685
704
result,
686
705
has_fields : false ,
706
+ has_key : false ,
707
+ state : Default :: default ( ) ,
687
708
}
688
709
}
689
710
@@ -712,25 +733,123 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
712
733
/// ```
713
734
#[ stable( feature = "debug_builders" , since = "1.2.0" ) ]
714
735
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
+
715
778
self . result = self . result . and_then ( |_| {
716
779
if self . is_pretty ( ) {
717
780
if !self . has_fields {
718
781
self . fmt . write_str ( "\n " ) ?;
719
782
}
720
783
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 ) ;
722
786
key. fmt ( & mut writer) ?;
723
787
writer. write_str ( ": " ) ?;
724
- value. fmt ( & mut writer) ?;
725
- writer. write_str ( ",\n " )
726
788
} else {
727
789
if self . has_fields {
728
790
self . fmt . write_str ( ", " ) ?
729
791
}
730
792
key. fmt ( self . fmt ) ?;
731
793
self . fmt . write_str ( ": " ) ?;
732
- value. fmt ( self . fmt )
733
794
}
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 ( ( ) )
734
853
} ) ;
735
854
736
855
self . has_fields = true ;
@@ -775,6 +894,11 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
775
894
776
895
/// Finishes output and returns any error encountered.
777
896
///
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
+ ///
778
902
/// # Examples
779
903
///
780
904
/// ```
@@ -797,6 +921,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
797
921
/// ```
798
922
#[ stable( feature = "debug_builders" , since = "1.2.0" ) ]
799
923
pub fn finish ( & mut self ) -> fmt:: Result {
924
+ assert ! ( !self . has_key, "attempted to finish a map with a partial entry" ) ;
925
+
800
926
self . result . and_then ( |_| self . fmt . write_str ( "}" ) )
801
927
}
802
928
0 commit comments