@@ -316,7 +316,7 @@ impl Spec {
316316 match self {
317317 Self :: Char { width, align_left } => {
318318 let ( width, neg_width) =
319- resolve_asterisk_maybe_negative ( * width, & mut args) . unwrap_or_default ( ) ;
319+ resolve_asterisk_width ( * width, & mut args) . unwrap_or_default ( ) ;
320320 write_padded ( writer, & [ args. get_char ( ) ] , width, * align_left || neg_width)
321321 }
322322 Self :: String {
@@ -325,15 +325,15 @@ impl Spec {
325325 precision,
326326 } => {
327327 let ( width, neg_width) =
328- resolve_asterisk_maybe_negative ( * width, & mut args) . unwrap_or_default ( ) ;
328+ resolve_asterisk_width ( * width, & mut args) . unwrap_or_default ( ) ;
329329
330330 // GNU does do this truncation on a byte level, see for instance:
331331 // printf "%.1s" 🙃
332332 // > �
333333 // For now, we let printf panic when we truncate within a code point.
334334 // TODO: We need to not use Rust's formatting for aligning the output,
335335 // so that we can just write bytes to stdout without panicking.
336- let precision = resolve_asterisk ( * precision, & mut args) ;
336+ let precision = resolve_asterisk_precision ( * precision, & mut args) ;
337337 let s = args. get_str ( ) ;
338338 let truncated = match precision {
339339 Some ( p) if p < s. len ( ) => & s[ ..p] ,
@@ -349,7 +349,7 @@ impl Spec {
349349 Self :: EscapedString => {
350350 let s = args. get_str ( ) ;
351351 let mut parsed = Vec :: new ( ) ;
352- for c in parse_escape_only ( s. as_bytes ( ) , OctalParsing :: default ( ) ) {
352+ for c in parse_escape_only ( s. as_bytes ( ) , OctalParsing :: ThreeDigits ) {
353353 match c. write ( & mut parsed) ? {
354354 ControlFlow :: Continue ( ( ) ) => { }
355355 ControlFlow :: Break ( ( ) ) => {
@@ -382,8 +382,10 @@ impl Spec {
382382 positive_sign,
383383 alignment,
384384 } => {
385- let width = resolve_asterisk ( * width, & mut args) . unwrap_or ( 0 ) ;
386- let precision = resolve_asterisk ( * precision, & mut args) . unwrap_or ( 0 ) ;
385+ let ( width, neg_width) =
386+ resolve_asterisk_width ( * width, & mut args) . unwrap_or ( ( 0 , false ) ) ;
387+ let precision =
388+ resolve_asterisk_precision ( * precision, & mut args) . unwrap_or_default ( ) ;
387389 let i = args. get_i64 ( ) ;
388390
389391 if precision as u64 > i32:: MAX as u64 {
@@ -394,7 +396,11 @@ impl Spec {
394396 width,
395397 precision,
396398 positive_sign : * positive_sign,
397- alignment : * alignment,
399+ alignment : if neg_width {
400+ NumberAlignment :: Left
401+ } else {
402+ * alignment
403+ } ,
398404 }
399405 . fmt ( writer, i)
400406 . map_err ( FormatError :: IoError )
@@ -405,8 +411,10 @@ impl Spec {
405411 precision,
406412 alignment,
407413 } => {
408- let width = resolve_asterisk ( * width, & mut args) . unwrap_or ( 0 ) ;
409- let precision = resolve_asterisk ( * precision, & mut args) . unwrap_or ( 0 ) ;
414+ let ( width, neg_width) =
415+ resolve_asterisk_width ( * width, & mut args) . unwrap_or ( ( 0 , false ) ) ;
416+ let precision =
417+ resolve_asterisk_precision ( * precision, & mut args) . unwrap_or_default ( ) ;
410418 let i = args. get_u64 ( ) ;
411419
412420 if precision as u64 > i32:: MAX as u64 {
@@ -417,7 +425,11 @@ impl Spec {
417425 variant : * variant,
418426 precision,
419427 width,
420- alignment : * alignment,
428+ alignment : if neg_width {
429+ NumberAlignment :: Left
430+ } else {
431+ * alignment
432+ } ,
421433 }
422434 . fmt ( writer, i)
423435 . map_err ( FormatError :: IoError )
@@ -431,8 +443,9 @@ impl Spec {
431443 alignment,
432444 precision,
433445 } => {
434- let width = resolve_asterisk ( * width, & mut args) . unwrap_or ( 0 ) ;
435- let precision = resolve_asterisk ( * precision, & mut args) . unwrap_or ( 6 ) ;
446+ let ( width, neg_width) =
447+ resolve_asterisk_width ( * width, & mut args) . unwrap_or ( ( 0 , false ) ) ;
448+ let precision = resolve_asterisk_precision ( * precision, & mut args) . unwrap_or ( 6 ) ;
436449 // TODO: We should implement some get_extendedBigDecimal function in args to avoid losing precision.
437450 let f: ExtendedBigDecimal = args. get_f64 ( ) . into ( ) ;
438451
@@ -447,7 +460,11 @@ impl Spec {
447460 case : * case,
448461 force_decimal : * force_decimal,
449462 positive_sign : * positive_sign,
450- alignment : * alignment,
463+ alignment : if neg_width {
464+ NumberAlignment :: Left
465+ } else {
466+ * alignment
467+ } ,
451468 }
452469 . fmt ( writer, & f)
453470 . map_err ( FormatError :: IoError )
@@ -456,18 +473,7 @@ impl Spec {
456473 }
457474}
458475
459- fn resolve_asterisk < ' a > (
460- option : Option < CanAsterisk < usize > > ,
461- mut args : impl ArgumentIter < ' a > ,
462- ) -> Option < usize > {
463- match option {
464- None => None ,
465- Some ( CanAsterisk :: Asterisk ) => Some ( usize:: try_from ( args. get_u64 ( ) ) . ok ( ) . unwrap_or ( 0 ) ) ,
466- Some ( CanAsterisk :: Fixed ( w) ) => Some ( w) ,
467- }
468- }
469-
470- fn resolve_asterisk_maybe_negative < ' a > (
476+ fn resolve_asterisk_width < ' a > (
471477 option : Option < CanAsterisk < usize > > ,
472478 mut args : impl ArgumentIter < ' a > ,
473479) -> Option < ( usize , bool ) > {
@@ -485,6 +491,17 @@ fn resolve_asterisk_maybe_negative<'a>(
485491 }
486492}
487493
494+ fn resolve_asterisk_precision < ' a > (
495+ option : Option < CanAsterisk < usize > > ,
496+ mut args : impl ArgumentIter < ' a > ,
497+ ) -> Option < usize > {
498+ match option {
499+ None => None ,
500+ Some ( CanAsterisk :: Asterisk ) => usize:: try_from ( args. get_i64_non_negative ( ) ) . ok ( ) ,
501+ Some ( CanAsterisk :: Fixed ( w) ) => Some ( w) ,
502+ }
503+ }
504+
488505fn write_padded (
489506 mut writer : impl Write ,
490507 text : & [ u8 ] ,
0 commit comments