@@ -297,10 +297,10 @@ impl Piece {
297297 if self . flags . contains ( Flag :: LeftPadding ) {
298298 write ! ( f, "{value}" )
299299 } else if self . padding == Padding :: Spaces {
300- let width = self . width . unwrap_or ( default_width) ;
300+ let width = self . pad_width ( f , b' ' , default_width) ? ;
301301 write ! ( f, "{value: >width$}" )
302302 } else {
303- let width = self . width . unwrap_or ( default_width) ;
303+ let width = self . pad_width ( f , b'0' , default_width) ? ;
304304 write ! ( f, "{value:0width$}" )
305305 }
306306 }
@@ -315,16 +315,24 @@ impl Piece {
315315 if self . flags . contains ( Flag :: LeftPadding ) {
316316 write ! ( f, "{value}" )
317317 } else if self . padding == Padding :: Zeros {
318- let width = self . width . unwrap_or ( default_width) ;
318+ let width = self . pad_width ( f , b'0' , default_width) ? ;
319319 write ! ( f, "{value:0width$}" )
320320 } else {
321- let width = self . width . unwrap_or ( default_width) ;
321+ let width = self . pad_width ( f , b' ' , default_width) ? ;
322322 write ! ( f, "{value: >width$}" )
323323 }
324324 }
325325
326+ /// Returns the width to use for the padding.
327+ ///
328+ /// Prints any excessive padding directly.
329+ fn pad_width ( & self , f : & mut SizeLimiter < ' _ > , pad : u8 , default : usize ) -> Result < usize , Error > {
330+ let width = self . width . unwrap_or ( default) ;
331+ f. pad ( pad, width. saturating_sub ( u16:: MAX . into ( ) ) ) ?;
332+ Ok ( width. min ( u16:: MAX . into ( ) ) )
333+ }
334+
326335 /// Format nanoseconds with the specified precision.
327- #[ allow( clippy:: uninlined_format_args) ] // for readability and symmetry between if branches
328336 fn format_nanoseconds (
329337 & self ,
330338 f : & mut SizeLimiter < ' _ > ,
@@ -335,38 +343,37 @@ impl Piece {
335343
336344 if width <= 9 {
337345 let value = nanoseconds / 10u32 . pow ( 9 - width as u32 ) ;
338- write ! ( f, "{value:0n $}" , n = width )
346+ write ! ( f, "{value:0width $}" )
339347 } else {
340- write ! ( f, "{nanoseconds:09}{:0n$}" , 0 , n = width - 9 )
348+ write ! ( f, "{nanoseconds:09}" ) ?;
349+ f. pad ( b'0' , width - 9 )
341350 }
342351 }
343352
344353 /// Format a string value.
345354 fn format_string ( & self , f : & mut SizeLimiter < ' _ > , s : & str ) -> Result < ( ) , Error > {
346- match self . width {
347- None => write ! ( f, "{s}" ) ,
348- Some ( width) => {
349- if self . flags . contains ( Flag :: LeftPadding ) {
350- write ! ( f, "{s}" )
351- } else if self . padding == Padding :: Zeros {
352- write ! ( f, "{s:0>width$}" )
353- } else {
354- write ! ( f, "{s: >width$}" )
355- }
356- }
355+ if !self . flags . contains ( Flag :: LeftPadding ) {
356+ self . write_padding ( f, s. len ( ) ) ?;
357357 }
358+
359+ write ! ( f, "{s}" )
358360 }
359361
360362 /// Write padding separately.
361363 fn write_padding ( & self , f : & mut SizeLimiter < ' _ > , min_width : usize ) -> Result < ( ) , Error > {
362- if let Some ( width) = self . width {
363- let n = width. saturating_sub ( min_width) ;
364+ let Some ( width) = self . width else {
365+ return Ok ( ( ) ) ;
366+ } ;
367+
368+ let n = width. saturating_sub ( min_width) ;
369+
370+ let pad = match self . padding {
371+ Padding :: Zeros => b'0' ,
372+ _ => b' ' ,
373+ } ;
374+
375+ f. pad ( pad, n) ?;
364376
365- match self . padding {
366- Padding :: Zeros => write ! ( f, "{:0>n$}" , "" ) ?,
367- _ => write ! ( f, "{: >n$}" , "" ) ?,
368- } ;
369- }
370377 Ok ( ( ) )
371378 }
372379
@@ -390,14 +397,34 @@ impl Piece {
390397 UtcOffset :: new ( hour, minute, second)
391398 }
392399
393- /// Compute hour padding for the `%z` specifier.
394- fn hour_padding ( & self , min_width : usize ) -> usize {
395- const MIN_PADDING : usize = "+hh" . len ( ) ;
400+ /// Write the hour sign.
401+ fn write_hour_sign ( f : & mut SizeLimiter < ' _ > , hour : f64 ) -> Result < ( ) , Error > {
402+ if hour. is_sign_negative ( ) {
403+ write ! ( f, "-" ) ?;
404+ } else {
405+ write ! ( f, "+" ) ?;
406+ }
407+
408+ Ok ( ( ) )
409+ }
396410
397- match self . width {
398- Some ( width) => width. saturating_sub ( min_width) + MIN_PADDING ,
399- None => MIN_PADDING ,
411+ /// Write the hour with padding for the `%z` specifier.
412+ fn write_offset_hour ( & self , f : & mut SizeLimiter < ' _ > , hour : f64 , w : usize ) -> Result < ( ) , Error > {
413+ let mut pad = self . width . unwrap_or ( 0 ) . saturating_sub ( w) ;
414+
415+ if hour < 10.0 {
416+ pad += 1 ;
417+ }
418+
419+ if self . padding == Padding :: Spaces {
420+ f. pad ( b' ' , pad) ?;
421+ Self :: write_hour_sign ( f, hour) ?;
422+ } else {
423+ Self :: write_hour_sign ( f, hour) ?;
424+ f. pad ( b'0' , pad) ?;
400425 }
426+
427+ write ! ( f, "{:.0}" , hour. abs( ) )
401428 }
402429
403430 /// Write the time zone UTC offset as `"+hh"`.
@@ -406,13 +433,7 @@ impl Piece {
406433 f : & mut SizeLimiter < ' _ > ,
407434 utc_offset : & UtcOffset ,
408435 ) -> Result < ( ) , Error > {
409- let hour = utc_offset. hour ;
410- let n = self . hour_padding ( "+hh" . len ( ) ) ;
411-
412- match self . padding {
413- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}" ) ,
414- _ => write ! ( f, "{hour:+0n$.0}" ) ,
415- }
436+ self . write_offset_hour ( f, utc_offset. hour , "+hh" . len ( ) )
416437 }
417438
418439 /// Write the time zone UTC offset as `"+hhmm"`.
@@ -421,13 +442,10 @@ impl Piece {
421442 f : & mut SizeLimiter < ' _ > ,
422443 utc_offset : & UtcOffset ,
423444 ) -> Result < ( ) , Error > {
424- let UtcOffset { hour, minute, .. } = utc_offset;
425- let n = self . hour_padding ( "+hhmm" . len ( ) ) ;
445+ let UtcOffset { hour, minute, .. } = * utc_offset;
426446
427- match self . padding {
428- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}{minute:02}" ) ,
429- _ => write ! ( f, "{hour:+0n$.0}{minute:02}" ) ,
430- }
447+ self . write_offset_hour ( f, hour, "+hhmm" . len ( ) ) ?;
448+ write ! ( f, "{minute:02}" )
431449 }
432450
433451 /// Write the time zone UTC offset as `"+hh:mm"`.
@@ -436,13 +454,10 @@ impl Piece {
436454 f : & mut SizeLimiter < ' _ > ,
437455 utc_offset : & UtcOffset ,
438456 ) -> Result < ( ) , Error > {
439- let UtcOffset { hour, minute, .. } = utc_offset;
440- let n = self . hour_padding ( "+hh:mm" . len ( ) ) ;
457+ let UtcOffset { hour, minute, .. } = * utc_offset;
441458
442- match self . padding {
443- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}:{minute:02}" ) ,
444- _ => write ! ( f, "{hour:+0n$.0}:{minute:02}" ) ,
445- }
459+ self . write_offset_hour ( f, hour, "+hh:mm" . len ( ) ) ?;
460+ write ! ( f, ":{minute:02}" )
446461 }
447462
448463 /// Write the time zone UTC offset as `"+hh:mm:ss"`.
@@ -455,14 +470,10 @@ impl Piece {
455470 hour,
456471 minute,
457472 second,
458- } = utc_offset;
459-
460- let n = self . hour_padding ( "+hh:mm:ss" . len ( ) ) ;
473+ } = * utc_offset;
461474
462- match self . padding {
463- Padding :: Spaces => write ! ( f, "{hour: >+n$.0}:{minute:02}:{second:02}" ) ,
464- _ => write ! ( f, "{hour:+0n$.0}:{minute:02}:{second:02}" ) ,
465- }
475+ self . write_offset_hour ( f, hour, "+hh:mm:ss" . len ( ) ) ?;
476+ write ! ( f, ":{minute:02}:{second:02}" )
466477 }
467478
468479 /// Format time using the formatting directive.
0 commit comments