@@ -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,16 +321,24 @@ 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 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 ( u16:: MAX . into ( ) ) ) ?;
338+ Ok ( width. min ( u16:: MAX . into ( ) ) )
339+ }
340+
332341 /// Format nanoseconds with the specified precision.
333- #[ allow( clippy:: uninlined_format_args) ] // for readability and symmetry between if branches
334342 fn format_nanoseconds (
335343 & self ,
336344 f : & mut SizeLimiter < ' _ > ,
@@ -341,38 +349,37 @@ impl Piece {
341349
342350 if width <= 9 {
343351 let value = nanoseconds / 10u32 . pow ( 9 - width as u32 ) ;
344- write ! ( f, "{value:0n $}" , n = width )
352+ write ! ( f, "{value:0width $}" )
345353 } else {
346- write ! ( f, "{nanoseconds:09}{:0n$}" , 0 , n = width - 9 )
354+ write ! ( f, "{nanoseconds:09}" ) ?;
355+ f. pad ( b'0' , width - 9 )
347356 }
348357 }
349358
350359 /// Format a string value.
351360 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- }
361+ if !self . flags . contains ( Flag :: LeftPadding ) {
362+ self . write_padding ( f, s. len ( ) ) ?;
363363 }
364+
365+ write ! ( f, "{s}" )
364366 }
365367
366368 /// Write padding separately.
367369 fn write_padding ( & self , f : & mut SizeLimiter < ' _ > , min_width : usize ) -> Result < ( ) , Error > {
368- if let Some ( width) = self . width {
369- let n = width. saturating_sub ( min_width) ;
370+ let Some ( width) = self . width else {
371+ return Ok ( ( ) ) ;
372+ } ;
373+
374+ let n = width. saturating_sub ( min_width) ;
375+
376+ let pad = match self . padding {
377+ Padding :: Zeros => b'0' ,
378+ _ => b' ' ,
379+ } ;
380+
381+ f. pad ( pad, n) ?;
370382
371- match self . padding {
372- Padding :: Zeros => write ! ( f, "{:0>n$}" , "" ) ?,
373- _ => write ! ( f, "{: >n$}" , "" ) ?,
374- } ;
375- }
376383 Ok ( ( ) )
377384 }
378385
@@ -396,14 +403,34 @@ impl Piece {
396403 UtcOffset :: new ( hour, minute, second)
397404 }
398405
399- /// Compute hour padding for the `%z` specifier.
400- fn hour_padding ( & self , min_width : usize ) -> usize {
401- const MIN_PADDING : usize = "+hh" . len ( ) ;
406+ /// Write the hour sign.
407+ fn write_hour_sign ( f : & mut SizeLimiter < ' _ > , hour : f64 ) -> Result < ( ) , Error > {
408+ if hour. is_sign_negative ( ) {
409+ write ! ( f, "-" ) ?;
410+ } else {
411+ write ! ( f, "+" ) ?;
412+ }
413+
414+ Ok ( ( ) )
415+ }
402416
403- match self . width {
404- Some ( width) => width. saturating_sub ( min_width) + MIN_PADDING ,
405- None => MIN_PADDING ,
417+ /// Write the hour with padding for the `%z` specifier.
418+ fn write_offset_hour ( & self , f : & mut SizeLimiter < ' _ > , hour : f64 , w : usize ) -> Result < ( ) , Error > {
419+ let mut pad = self . width . unwrap_or ( 0 ) . saturating_sub ( w) ;
420+
421+ if hour < 10.0 {
422+ pad += 1 ;
423+ }
424+
425+ if self . padding == Padding :: Spaces {
426+ f. pad ( b' ' , pad) ?;
427+ Self :: write_hour_sign ( f, hour) ?;
428+ } else {
429+ Self :: write_hour_sign ( f, hour) ?;
430+ f. pad ( b'0' , pad) ?;
406431 }
432+
433+ write ! ( f, "{:.0}" , hour. abs( ) )
407434 }
408435
409436 /// Write the time zone UTC offset as `"+hh"`.
@@ -412,13 +439,7 @@ impl Piece {
412439 f : & mut SizeLimiter < ' _ > ,
413440 utc_offset : & UtcOffset ,
414441 ) -> 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- }
442+ self . write_offset_hour ( f, utc_offset. hour , "+hh" . len ( ) )
422443 }
423444
424445 /// Write the time zone UTC offset as `"+hhmm"`.
@@ -427,13 +448,10 @@ impl Piece {
427448 f : & mut SizeLimiter < ' _ > ,
428449 utc_offset : & UtcOffset ,
429450 ) -> Result < ( ) , Error > {
430- let UtcOffset { hour, minute, .. } = utc_offset;
431- let n = self . hour_padding ( "+hhmm" . len ( ) ) ;
451+ let UtcOffset { hour, minute, .. } = * utc_offset;
432452
433- match self . padding {
434- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}{minute:02}" ) ,
435- _ => write ! ( f, "{hour:+0n$.0}{minute:02}" ) ,
436- }
453+ self . write_offset_hour ( f, hour, "+hhmm" . len ( ) ) ?;
454+ write ! ( f, "{minute:02}" )
437455 }
438456
439457 /// Write the time zone UTC offset as `"+hh:mm"`.
@@ -442,13 +460,10 @@ impl Piece {
442460 f : & mut SizeLimiter < ' _ > ,
443461 utc_offset : & UtcOffset ,
444462 ) -> Result < ( ) , Error > {
445- let UtcOffset { hour, minute, .. } = utc_offset;
446- let n = self . hour_padding ( "+hh:mm" . len ( ) ) ;
463+ let UtcOffset { hour, minute, .. } = * utc_offset;
447464
448- match self . padding {
449- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}:{minute:02}" ) ,
450- _ => write ! ( f, "{hour:+0n$.0}:{minute:02}" ) ,
451- }
465+ self . write_offset_hour ( f, hour, "+hh:mm" . len ( ) ) ?;
466+ write ! ( f, ":{minute:02}" )
452467 }
453468
454469 /// Write the time zone UTC offset as `"+hh:mm:ss"`.
@@ -461,14 +476,10 @@ impl Piece {
461476 hour,
462477 minute,
463478 second,
464- } = utc_offset;
465-
466- let n = self . hour_padding ( "+hh:mm:ss" . len ( ) ) ;
479+ } = * utc_offset;
467480
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- }
481+ self . write_offset_hour ( f, hour, "+hh:mm:ss" . len ( ) ) ?;
482+ write ! ( f, ":{minute:02}:{second:02}" )
472483 }
473484
474485 /// Format time using the formatting directive.
0 commit comments