@@ -1036,6 +1036,27 @@ 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 : char ,
1043
+ padding : usize ,
1044
+ }
1045
+
1046
+ impl PostPadding {
1047
+ fn new ( fill : char , padding : usize ) -> PostPadding {
1048
+ PostPadding { fill, padding }
1049
+ }
1050
+
1051
+ /// Write this post padding.
1052
+ fn write ( self , buf : & mut dyn Write ) -> Result {
1053
+ for _ in 0 ..self . padding {
1054
+ buf. write_char ( self . fill ) ?;
1055
+ }
1056
+ Ok ( ( ) )
1057
+ }
1058
+ }
1059
+
1039
1060
impl < ' a > Formatter < ' a > {
1040
1061
fn wrap_buf < ' b , ' c , F > ( & ' b mut self , wrap : F ) -> Formatter < ' c >
1041
1062
where ' b : ' c , F : FnOnce ( & ' b mut ( dyn Write +' b ) ) -> & ' c mut ( dyn Write +' c )
@@ -1153,47 +1174,56 @@ impl<'a> Formatter<'a> {
1153
1174
sign = Some ( '+' ) ; width += 1 ;
1154
1175
}
1155
1176
1156
- let prefixed = self . alternate ( ) ;
1157
- if prefixed {
1177
+ let prefix = if self . alternate ( ) {
1158
1178
width += prefix. chars ( ) . count ( ) ;
1159
- }
1179
+ Some ( prefix)
1180
+ } else {
1181
+ None
1182
+ } ;
1160
1183
1161
1184
// Writes the sign if it exists, and then the prefix if it was requested
1162
- let write_prefix = |f : & mut Formatter | {
1185
+ #[ inline( never) ]
1186
+ fn write_prefix ( f : & mut Formatter , sign : Option < char > , prefix : Option < & str > ) -> Result {
1163
1187
if let Some ( c) = sign {
1164
1188
f. buf . write_char ( c) ?;
1165
1189
}
1166
- if prefixed { f. buf . write_str ( prefix) }
1167
- else { Ok ( ( ) ) }
1168
- } ;
1190
+ if let Some ( prefix) = prefix {
1191
+ f. buf . write_str ( prefix)
1192
+ } else {
1193
+ Ok ( ( ) )
1194
+ }
1195
+ }
1169
1196
1170
1197
// The `width` field is more of a `min-width` parameter at this point.
1171
1198
match self . width {
1172
1199
// If there's no minimum length requirements then we can just
1173
1200
// write the bytes.
1174
1201
None => {
1175
- write_prefix ( self ) ?; self . buf . write_str ( buf)
1202
+ write_prefix ( self , sign, prefix) ?;
1203
+ self . buf . write_str ( buf)
1176
1204
}
1177
1205
// Check if we're over the minimum width, if so then we can also
1178
1206
// just write the bytes.
1179
1207
Some ( min) if width >= min => {
1180
- write_prefix ( self ) ?; self . buf . write_str ( buf)
1208
+ write_prefix ( self , sign, prefix) ?;
1209
+ self . buf . write_str ( buf)
1181
1210
}
1182
1211
// The sign and prefix goes before the padding if the fill character
1183
1212
// is zero
1184
1213
Some ( min) if self . sign_aware_zero_pad ( ) => {
1185
1214
self . fill = '0' ;
1186
1215
self . align = rt:: v1:: Alignment :: Right ;
1187
- write_prefix ( self ) ?;
1188
- self . with_padding ( min - width, rt:: v1:: Alignment :: Right , |f| {
1189
- f . buf . write_str ( buf)
1190
- } )
1216
+ write_prefix ( self , sign , prefix ) ?;
1217
+ let post_padding = self . padding ( min - width, rt:: v1:: Alignment :: Right ) ? ;
1218
+ self . buf . write_str ( buf) ? ;
1219
+ post_padding . write ( self . buf )
1191
1220
}
1192
1221
// Otherwise, the sign and prefix goes after the padding
1193
1222
Some ( min) => {
1194
- self . with_padding ( min - width, rt:: v1:: Alignment :: Right , |f| {
1195
- write_prefix ( f) ?; f. buf . write_str ( buf)
1196
- } )
1223
+ let post_padding = self . padding ( min - width, rt:: v1:: Alignment :: Right ) ?;
1224
+ write_prefix ( self , sign, prefix) ?;
1225
+ self . buf . write_str ( buf) ?;
1226
+ post_padding. write ( self . buf )
1197
1227
}
1198
1228
}
1199
1229
}
@@ -1264,19 +1294,21 @@ impl<'a> Formatter<'a> {
1264
1294
// up the minimum width with the specified string + some alignment.
1265
1295
Some ( width) => {
1266
1296
let align = rt:: v1:: Alignment :: Left ;
1267
- self . with_padding ( width - s. chars ( ) . count ( ) , align, |me| {
1268
- me . buf . write_str ( s)
1269
- } )
1297
+ let post_padding = self . padding ( width - s. chars ( ) . count ( ) , align) ? ;
1298
+ self . buf . write_str ( s) ? ;
1299
+ post_padding . write ( self . buf )
1270
1300
}
1271
1301
}
1272
1302
}
1273
1303
1274
- /// Runs a callback, emitting the correct padding either before or
1275
- /// afterwards depending on whether right or left alignment is requested.
1276
- fn with_padding < F > ( & mut self , padding : usize , default : rt:: v1:: Alignment ,
1277
- f : F ) -> Result
1278
- where F : FnOnce ( & mut Formatter ) -> Result ,
1279
- {
1304
+ /// Write the pre-padding and return the unwritten post-padding. Callers are
1305
+ /// responsible for ensuring post-padding is written after the thing that is
1306
+ /// being padded.
1307
+ fn padding (
1308
+ & mut self ,
1309
+ padding : usize ,
1310
+ default : rt:: v1:: Alignment
1311
+ ) -> result:: Result < PostPadding , Error > {
1280
1312
let align = match self . align {
1281
1313
rt:: v1:: Alignment :: Unknown => default,
1282
1314
_ => self . align
@@ -1289,20 +1321,11 @@ impl<'a> Formatter<'a> {
1289
1321
rt:: v1:: Alignment :: Center => ( padding / 2 , ( padding + 1 ) / 2 ) ,
1290
1322
} ;
1291
1323
1292
- let mut fill = [ 0 ; 4 ] ;
1293
- let fill = self . fill . encode_utf8 ( & mut fill) ;
1294
-
1295
1324
for _ in 0 ..pre_pad {
1296
- self . buf . write_str ( fill) ?;
1297
- }
1298
-
1299
- f ( self ) ?;
1300
-
1301
- for _ in 0 ..post_pad {
1302
- self . buf . write_str ( fill) ?;
1325
+ self . buf . write_char ( self . fill ) ?;
1303
1326
}
1304
1327
1305
- Ok ( ( ) )
1328
+ Ok ( PostPadding :: new ( self . fill , post_pad ) )
1306
1329
}
1307
1330
1308
1331
/// Takes the formatted parts and applies the padding.
@@ -1334,9 +1357,9 @@ impl<'a> Formatter<'a> {
1334
1357
let ret = if width <= len { // no padding
1335
1358
self . write_formatted_parts ( & formatted)
1336
1359
} else {
1337
- self . with_padding ( width - len, align, |f| {
1338
- f . write_formatted_parts ( & formatted)
1339
- } )
1360
+ let post_padding = self . padding ( width - len, align) ? ;
1361
+ self . write_formatted_parts ( & formatted) ? ;
1362
+ post_padding . write ( self . buf )
1340
1363
} ;
1341
1364
self . fill = old_fill;
1342
1365
self . align = old_align;
0 commit comments