@@ -314,15 +314,17 @@ impl Spec {
314314 ) -> Result < ( ) , FormatError > {
315315 match self {
316316 Self :: Char { width, align_left } => {
317- let width = resolve_asterisk ( * width, & mut args) ?. unwrap_or ( 0 ) ;
318- write_padded ( writer, & [ args. get_char ( ) ] , width, * align_left)
317+ let ( width, neg_width) =
318+ resolve_asterisk_maybe_negative ( * width, & mut args) ?. unwrap_or_default ( ) ;
319+ write_padded ( writer, & [ args. get_char ( ) ] , width, * align_left || neg_width)
319320 }
320321 Self :: String {
321322 width,
322323 align_left,
323324 precision,
324325 } => {
325- let width = resolve_asterisk ( * width, & mut args) ?. unwrap_or ( 0 ) ;
326+ let ( width, neg_width) =
327+ resolve_asterisk_maybe_negative ( * width, & mut args) ?. unwrap_or_default ( ) ;
326328
327329 // GNU does do this truncation on a byte level, see for instance:
328330 // printf "%.1s" 🙃
@@ -336,7 +338,12 @@ impl Spec {
336338 Some ( p) if p < s. len ( ) => & s[ ..p] ,
337339 _ => s,
338340 } ;
339- write_padded ( writer, truncated. as_bytes ( ) , width, * align_left)
341+ write_padded (
342+ writer,
343+ truncated. as_bytes ( ) ,
344+ width,
345+ * align_left || neg_width,
346+ )
340347 }
341348 Self :: EscapedString => {
342349 let s = args. get_str ( ) ;
@@ -458,6 +465,24 @@ fn resolve_asterisk<'a>(
458465 } )
459466}
460467
468+ fn resolve_asterisk_maybe_negative < ' a > (
469+ option : Option < CanAsterisk < usize > > ,
470+ mut args : impl ArgumentIter < ' a > ,
471+ ) -> Result < Option < ( usize , bool ) > , FormatError > {
472+ Ok ( match option {
473+ None => None ,
474+ Some ( CanAsterisk :: Asterisk ) => {
475+ let nb = args. get_i64 ( ) ;
476+ if nb < 0 {
477+ Some ( ( usize:: try_from ( -( nb as isize ) ) . ok ( ) . unwrap_or ( 0 ) , true ) )
478+ } else {
479+ Some ( ( usize:: try_from ( nb) . ok ( ) . unwrap_or ( 0 ) , false ) )
480+ }
481+ }
482+ Some ( CanAsterisk :: Fixed ( w) ) => Some ( ( w, false ) ) ,
483+ } )
484+ }
485+
461486fn write_padded (
462487 mut writer : impl Write ,
463488 text : & [ u8 ] ,
0 commit comments