@@ -1036,6 +1036,32 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
1036
1036
Ok ( ( ) )
1037
1037
}
1038
1038
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
+
1039
1065
impl < ' a > Formatter < ' a > {
1040
1066
fn wrap_buf < ' b , ' c , F > ( & ' b mut self , wrap : F ) -> Formatter < ' c >
1041
1067
where ' b : ' c , F : FnOnce ( & ' b mut ( dyn Write +' b ) ) -> & ' c mut ( dyn Write +' c )
@@ -1193,16 +1219,16 @@ impl<'a> Formatter<'a> {
1193
1219
self . fill = '0' ;
1194
1220
self . align = rt:: v1:: Alignment :: Right ;
1195
1221
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 )
1199
1225
}
1200
1226
// Otherwise, the sign and prefix goes after the padding
1201
1227
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 )
1206
1232
}
1207
1233
}
1208
1234
}
@@ -1273,19 +1299,21 @@ impl<'a> Formatter<'a> {
1273
1299
// up the minimum width with the specified string + some alignment.
1274
1300
Some ( width) => {
1275
1301
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 )
1279
1305
}
1280
1306
}
1281
1307
}
1282
1308
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 > {
1289
1317
let align = match self . align {
1290
1318
rt:: v1:: Alignment :: Unknown => default,
1291
1319
_ => self . align
@@ -1299,19 +1327,19 @@ impl<'a> Formatter<'a> {
1299
1327
} ;
1300
1328
1301
1329
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) ;
1307
1332
1308
- f ( self ) ?;
1333
+ for _ in 0 ..pre_pad {
1334
+ self . buf . write_str ( fill) ?;
1335
+ }
1309
1336
1310
- for _ in 0 ..post_pad {
1311
- self . buf . write_str ( fill) ?;
1312
- }
1337
+ fill. len ( )
1338
+ } ;
1313
1339
1314
- Ok ( ( ) )
1340
+ Ok ( unsafe {
1341
+ PostPadding :: new ( fill, fill_len as u32 , post_pad)
1342
+ } )
1315
1343
}
1316
1344
1317
1345
/// Takes the formatted parts and applies the padding.
@@ -1343,9 +1371,9 @@ impl<'a> Formatter<'a> {
1343
1371
let ret = if width <= len { // no padding
1344
1372
self . write_formatted_parts ( & formatted)
1345
1373
} 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 )
1349
1377
} ;
1350
1378
self . fill = old_fill;
1351
1379
self . align = old_align;
0 commit comments