@@ -1036,6 +1036,32 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
10361036 Ok ( ( ) )
10371037}
10381038
1039+ /// Padding after the end of something. Returned by `Formatter::padding`.
1040+ #[ must_use = "don't forget to write the post padding" ]
1041+ struct PostPadding {
1042+ fill : [ u8 ; 4 ] ,
1043+ fill_len : u32 ,
1044+ padding : usize ,
1045+ }
1046+
1047+ impl PostPadding {
1048+ /// Safety relies on `fill[..fill_len]` being a valid UTF-8 char.
1049+ unsafe fn new ( fill : [ u8 ; 4 ] , fill_len : u32 , padding : usize ) -> PostPadding {
1050+ PostPadding { fill, fill_len, padding }
1051+ }
1052+
1053+ /// Write this post padding.
1054+ fn write ( self , buf : & mut dyn Write ) -> Result {
1055+ let fill = unsafe {
1056+ str:: from_utf8_unchecked ( & self . fill . get_unchecked ( ..self . fill_len as usize ) )
1057+ } ;
1058+ for _ in 0 ..self . padding {
1059+ buf. write_str ( fill) ?;
1060+ }
1061+ Ok ( ( ) )
1062+ }
1063+ }
1064+
10391065impl < ' a > Formatter < ' a > {
10401066 fn wrap_buf < ' b , ' c , F > ( & ' b mut self , wrap : F ) -> Formatter < ' c >
10411067 where ' b : ' c , F : FnOnce ( & ' b mut ( dyn Write +' b ) ) -> & ' c mut ( dyn Write +' c )
@@ -1193,16 +1219,16 @@ impl<'a> Formatter<'a> {
11931219 self . fill = '0' ;
11941220 self . align = rt:: v1:: Alignment :: Right ;
11951221 write_prefix ( self , sign, prefix) ?;
1196- self . with_padding ( min - width, rt:: v1:: Alignment :: Right , |f| {
1197- f . buf . write_str ( buf)
1198- } )
1222+ let post_padding = self . padding ( min - width, rt:: v1:: Alignment :: Right ) ? ;
1223+ self . buf . write_str ( buf) ? ;
1224+ post_padding . write ( self . buf )
11991225 }
12001226 // Otherwise, the sign and prefix goes after the padding
12011227 Some ( min) => {
1202- self . with_padding ( min - width, rt:: v1:: Alignment :: Right , |f| {
1203- write_prefix ( f , sign, prefix) ?;
1204- f . buf . write_str ( buf)
1205- } )
1228+ let post_padding = self . padding ( min - width, rt:: v1:: Alignment :: Right ) ? ;
1229+ write_prefix ( self , sign, prefix) ?;
1230+ self . buf . write_str ( buf) ? ;
1231+ post_padding . write ( self . buf )
12061232 }
12071233 }
12081234 }
@@ -1273,19 +1299,21 @@ impl<'a> Formatter<'a> {
12731299 // up the minimum width with the specified string + some alignment.
12741300 Some ( width) => {
12751301 let align = rt:: v1:: Alignment :: Left ;
1276- self . with_padding ( width - s. chars ( ) . count ( ) , align, |me| {
1277- me . buf . write_str ( s)
1278- } )
1302+ let post_padding = self . padding ( width - s. chars ( ) . count ( ) , align) ? ;
1303+ self . buf . write_str ( s) ? ;
1304+ post_padding . write ( self . buf )
12791305 }
12801306 }
12811307 }
12821308
1283- /// Runs a callback, emitting the correct padding either before or
1284- /// afterwards depending on whether right or left alignment is requested.
1285- fn with_padding < F > ( & mut self , padding : usize , default : rt:: v1:: Alignment ,
1286- f : F ) -> Result
1287- where F : FnOnce ( & mut Formatter ) -> Result ,
1288- {
1309+ /// Write the pre-padding and return the unwritten post-padding. Callers are
1310+ /// responsible for ensuring post-padding is written after the thing that is
1311+ /// being padded.
1312+ fn padding (
1313+ & mut self ,
1314+ padding : usize ,
1315+ default : rt:: v1:: Alignment
1316+ ) -> result:: Result < PostPadding , Error > {
12891317 let align = match self . align {
12901318 rt:: v1:: Alignment :: Unknown => default,
12911319 _ => self . align
@@ -1299,19 +1327,19 @@ impl<'a> Formatter<'a> {
12991327 } ;
13001328
13011329 let mut fill = [ 0 ; 4 ] ;
1302- let fill = self . fill . encode_utf8 ( & mut fill) ;
1303-
1304- for _ in 0 ..pre_pad {
1305- self . buf . write_str ( fill) ?;
1306- }
1330+ let fill_len = {
1331+ let fill = self . fill . encode_utf8 ( & mut fill) ;
13071332
1308- f ( self ) ?;
1333+ for _ in 0 ..pre_pad {
1334+ self . buf . write_str ( fill) ?;
1335+ }
13091336
1310- for _ in 0 ..post_pad {
1311- self . buf . write_str ( fill) ?;
1312- }
1337+ fill. len ( )
1338+ } ;
13131339
1314- Ok ( ( ) )
1340+ Ok ( unsafe {
1341+ PostPadding :: new ( fill, fill_len as u32 , post_pad)
1342+ } )
13151343 }
13161344
13171345 /// Takes the formatted parts and applies the padding.
@@ -1343,9 +1371,9 @@ impl<'a> Formatter<'a> {
13431371 let ret = if width <= len { // no padding
13441372 self . write_formatted_parts ( & formatted)
13451373 } else {
1346- self . with_padding ( width - len, align, |f| {
1347- f . write_formatted_parts ( & formatted)
1348- } )
1374+ let post_padding = self . padding ( width - len, align) ? ;
1375+ self . write_formatted_parts ( & formatted) ? ;
1376+ post_padding . write ( self . buf )
13491377 } ;
13501378 self . fill = old_fill;
13511379 self . align = old_align;
0 commit comments