@@ -303,10 +303,10 @@ impl Piece {
303303 if self . flags . contains ( Flag :: LeftPadding ) {
304304 write ! ( f, "{value}" )
305305 } else if self . padding == Padding :: Spaces {
306- let width = self . width . unwrap_or ( default_width) ;
306+ let width = self . pad_width ( f , b' ' , default_width) ? ;
307307 write ! ( f, "{value: >width$}" )
308308 } else {
309- let width = self . width . unwrap_or ( default_width) ;
309+ let width = self . pad_width ( f , b'0' , default_width) ? ;
310310 write ! ( f, "{value:0width$}" )
311311 }
312312 }
@@ -321,14 +321,23 @@ impl Piece {
321321 if self . flags . contains ( Flag :: LeftPadding ) {
322322 write ! ( f, "{value}" )
323323 } else if self . padding == Padding :: Zeros {
324- let width = self . width . unwrap_or ( default_width) ;
324+ let width = self . pad_width ( f , b'0' , default_width) ? ;
325325 write ! ( f, "{value:0width$}" )
326326 } else {
327- let width = self . width . unwrap_or ( default_width) ;
327+ let width = self . pad_width ( f , b' ' , default_width) ? ;
328328 write ! ( f, "{value: >width$}" )
329329 }
330330 }
331331
332+ // Returns the width to use for the padding.
333+ //
334+ // Prints any excessive (>10) padding directly.
335+ fn pad_width ( & self , f : & mut SizeLimiter < ' _ > , pad : u8 , default : usize ) -> Result < usize , Error > {
336+ let width = self . width . unwrap_or ( default) ;
337+ f. pad ( pad, width. saturating_sub ( 10 ) ) ?;
338+ Ok ( width. min ( 10 ) )
339+ }
340+
332341 /// Format nanoseconds with the specified precision.
333342 #[ allow( clippy:: uninlined_format_args) ] // for readability and symmetry between if branches
334343 fn format_nanoseconds (
@@ -343,35 +352,30 @@ impl Piece {
343352 let value = nanoseconds / 10u32 . pow ( 9 - width as u32 ) ;
344353 write ! ( f, "{value:0n$}" , n = width)
345354 } else {
346- write ! ( f, "{nanoseconds:09}{:0n$}" , 0 , n = width - 9 )
355+ write ! ( f, "{nanoseconds:09}" ) ?;
356+ f. pad ( b'0' , width - 9 )
347357 }
348358 }
349359
350360 /// Format a string value.
351361 fn format_string ( & self , f : & mut SizeLimiter < ' _ > , s : & str ) -> Result < ( ) , Error > {
352- match self . width {
353- None => write ! ( f, "{s}" ) ,
354- Some ( width) => {
355- if self . flags . contains ( Flag :: LeftPadding ) {
356- write ! ( f, "{s}" )
357- } else if self . padding == Padding :: Zeros {
358- write ! ( f, "{s:0>width$}" )
359- } else {
360- write ! ( f, "{s: >width$}" )
361- }
362- }
362+ if !self . flags . contains ( Flag :: LeftPadding ) {
363+ self . write_padding ( f, s. len ( ) ) ?;
363364 }
365+ write ! ( f, "{s}" )
364366 }
365367
366368 /// Write padding separately.
367369 fn write_padding ( & self , f : & mut SizeLimiter < ' _ > , min_width : usize ) -> Result < ( ) , Error > {
368370 if let Some ( width) = self . width {
369371 let n = width. saturating_sub ( min_width) ;
370372
371- match self . padding {
372- Padding :: Zeros => write ! ( f , "{:0>n$}" , "" ) ? ,
373- _ => write ! ( f , "{: >n$}" , "" ) ? ,
373+ let pad = match self . padding {
374+ Padding :: Zeros => b'0' ,
375+ _ => b' ' ,
374376 } ;
377+
378+ f. pad ( pad, n) ?;
375379 }
376380 Ok ( ( ) )
377381 }
@@ -396,14 +400,24 @@ impl Piece {
396400 UtcOffset :: new ( hour, minute, second)
397401 }
398402
399- /// Compute hour padding for the `%z` specifier.
400- fn hour_padding ( & self , min_width : usize ) -> usize {
401- const MIN_PADDING : usize = "+hh" . len ( ) ;
402-
403- match self . width {
404- Some ( width) => width. saturating_sub ( min_width) + MIN_PADDING ,
405- None => MIN_PADDING ,
403+ /// Print the hour with padding for the `%z` specifier.
404+ fn write_offset_hour ( & self , f : & mut SizeLimiter < ' _ > , hour : f64 , w : usize ) -> Result < ( ) , Error > {
405+ let mut pad = self . width . unwrap_or ( 0 ) . saturating_sub ( w) ;
406+ if hour < 10.0 {
407+ pad += 1 ;
408+ }
409+ if self . padding == Padding :: Spaces {
410+ f. pad ( b' ' , pad) ?;
411+ }
412+ if hour. is_sign_negative ( ) {
413+ write ! ( f, "-" ) ?;
414+ } else {
415+ write ! ( f, "+" ) ?;
406416 }
417+ if self . padding != Padding :: Spaces {
418+ f. pad ( b'0' , pad) ?;
419+ }
420+ write ! ( f, "{:.0}" , hour. abs( ) )
407421 }
408422
409423 /// Write the time zone UTC offset as `"+hh"`.
@@ -412,13 +426,7 @@ impl Piece {
412426 f : & mut SizeLimiter < ' _ > ,
413427 utc_offset : & UtcOffset ,
414428 ) -> Result < ( ) , Error > {
415- let hour = utc_offset. hour ;
416- let n = self . hour_padding ( "+hh" . len ( ) ) ;
417-
418- match self . padding {
419- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}" ) ,
420- _ => write ! ( f, "{hour:+0n$.0}" ) ,
421- }
429+ self . write_offset_hour ( f, utc_offset. hour , "+hh" . len ( ) )
422430 }
423431
424432 /// Write the time zone UTC offset as `"+hhmm"`.
@@ -428,12 +436,8 @@ impl Piece {
428436 utc_offset : & UtcOffset ,
429437 ) -> Result < ( ) , Error > {
430438 let UtcOffset { hour, minute, .. } = utc_offset;
431- let n = self . hour_padding ( "+hhmm" . len ( ) ) ;
432-
433- match self . padding {
434- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}{minute:02}" ) ,
435- _ => write ! ( f, "{hour:+0n$.0}{minute:02}" ) ,
436- }
439+ self . write_offset_hour ( f, * hour, "+hhmm" . len ( ) ) ?;
440+ write ! ( f, "{minute:02}" )
437441 }
438442
439443 /// Write the time zone UTC offset as `"+hh:mm"`.
@@ -443,12 +447,8 @@ impl Piece {
443447 utc_offset : & UtcOffset ,
444448 ) -> Result < ( ) , Error > {
445449 let UtcOffset { hour, minute, .. } = utc_offset;
446- let n = self . hour_padding ( "+hh:mm" . len ( ) ) ;
447-
448- match self . padding {
449- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}:{minute:02}" ) ,
450- _ => write ! ( f, "{hour:+0n$.0}:{minute:02}" ) ,
451- }
450+ self . write_offset_hour ( f, * hour, "+hh:mm" . len ( ) ) ?;
451+ write ! ( f, ":{minute:02}" )
452452 }
453453
454454 /// Write the time zone UTC offset as `"+hh:mm:ss"`.
@@ -462,13 +462,8 @@ impl Piece {
462462 minute,
463463 second,
464464 } = utc_offset;
465-
466- let n = self . hour_padding ( "+hh:mm:ss" . len ( ) ) ;
467-
468- match self . padding {
469- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}:{minute:02}:{second:02}" ) ,
470- _ => write ! ( f, "{hour:+0n$.0}:{minute:02}:{second:02}" ) ,
471- }
465+ self . write_offset_hour ( f, * hour, "+hh:mm:ss" . len ( ) ) ?;
466+ write ! ( f, ":{minute:02}:{second:02}" )
472467 }
473468
474469 /// Format time using the formatting directive.
0 commit comments