@@ -334,9 +334,15 @@ const BAD_FORMAT: ParseError = ParseError(ParseErrorKind::BadFormat);
334334
335335/// Tries to format given arguments with given formatting items.
336336/// Internally used by `DelayedFormat`.
337- pub fn format < ' a , I > ( w : & mut fmt:: Formatter , date : Option < & NaiveDate > , time : Option < & NaiveTime > ,
338- off : Option < & ( String , FixedOffset ) > , items : I ) -> fmt:: Result
339- where I : Iterator < Item =Item < ' a > > {
337+ pub fn format < ' a , I > (
338+ w : & mut fmt:: Formatter ,
339+ date : Option < & NaiveDate > ,
340+ time : Option < & NaiveTime > ,
341+ off : Option < & ( String , FixedOffset ) > ,
342+ items : I ,
343+ ) -> fmt:: Result
344+ where I : Iterator < Item =Item < ' a > >
345+ {
340346 // full and abbreviated month and weekday names
341347 static SHORT_MONTHS : [ & ' static str ; 12 ] =
342348 [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] ;
@@ -348,10 +354,13 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
348354 static LONG_WEEKDAYS : [ & ' static str ; 7 ] =
349355 [ "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" , "Sunday" ] ;
350356
357+ use std:: fmt:: Write ;
358+ let mut result = String :: new ( ) ;
359+
351360 for item in items {
352361 match item {
353- Item :: Literal ( s) | Item :: Space ( s) => try! ( write ! ( w , "{}" , s ) ) ,
354- Item :: OwnedLiteral ( ref s) | Item :: OwnedSpace ( ref s) => try! ( write ! ( w , "{}" , s ) ) ,
362+ Item :: Literal ( s) | Item :: Space ( s) => result . push_str ( s ) ,
363+ Item :: OwnedLiteral ( ref s) | Item :: OwnedSpace ( ref s) => result . push_str ( s ) ,
355364
356365 Item :: Numeric ( spec, pad) => {
357366 use self :: Numeric :: * ;
@@ -398,23 +407,26 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
398407 Internal ( ref int) => match int. _dummy { } ,
399408 } ;
400409
410+
401411 if let Some ( v) = v {
402- if ( spec == Year || spec == IsoYear ) && !( 0 <= v && v < 10_000 ) {
403- // non-four-digit years require an explicit sign as per ISO 8601
404- match pad {
405- Pad :: None => try!( write ! ( w, "{:+}" , v) ) ,
406- Pad :: Zero => try!( write ! ( w, "{:+01$}" , v, width + 1 ) ) ,
407- Pad :: Space => try!( write ! ( w, "{:+1$}" , v, width + 1 ) ) ,
408- }
409- } else {
410- match pad {
411- Pad :: None => try!( write ! ( w, "{}" , v) ) ,
412- Pad :: Zero => try!( write ! ( w, "{:01$}" , v, width) ) ,
413- Pad :: Space => try!( write ! ( w, "{:1$}" , v, width) ) ,
412+ try!(
413+ if ( spec == Year || spec == IsoYear ) && !( 0 <= v && v < 10_000 ) {
414+ // non-four-digit years require an explicit sign as per ISO 8601
415+ match pad {
416+ Pad :: None => write ! ( result, "{:+}" , v) ,
417+ Pad :: Zero => write ! ( result, "{:+01$}" , v, width + 1 ) ,
418+ Pad :: Space => write ! ( result, "{:+1$}" , v, width + 1 ) ,
419+ }
420+ } else {
421+ match pad {
422+ Pad :: None => write ! ( result, "{}" , v) ,
423+ Pad :: Zero => write ! ( result, "{:01$}" , v, width) ,
424+ Pad :: Space => write ! ( result, "{:1$}" , v, width) ,
425+ }
414426 }
415- }
427+ )
416428 } else {
417- return Err ( fmt:: Error ) ; // insufficient arguments for given format
429+ return Err ( fmt:: Error ) // insufficient arguments for given format
418430 }
419431 } ,
420432
@@ -423,108 +435,139 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
423435
424436 /// Prints an offset from UTC in the format of `+HHMM` or `+HH:MM`.
425437 /// `Z` instead of `+00[:]00` is allowed when `allow_zulu` is true.
426- fn write_local_minus_utc ( w : & mut fmt:: Formatter , off : FixedOffset ,
427- allow_zulu : bool , use_colon : bool ) -> fmt:: Result {
438+ fn write_local_minus_utc (
439+ result : & mut String ,
440+ off : FixedOffset ,
441+ allow_zulu : bool ,
442+ use_colon : bool ,
443+ ) -> fmt:: Result {
428444 let off = off. local_minus_utc ( ) ;
429445 if !allow_zulu || off != 0 {
430446 let ( sign, off) = if off < 0 { ( '-' , -off) } else { ( '+' , off) } ;
431447 if use_colon {
432- write ! ( w , "{}{:02}:{:02}" , sign, off / 3600 , off / 60 % 60 )
448+ write ! ( result , "{}{:02}:{:02}" , sign, off / 3600 , off / 60 % 60 )
433449 } else {
434- write ! ( w , "{}{:02}{:02}" , sign, off / 3600 , off / 60 % 60 )
450+ write ! ( result , "{}{:02}{:02}" , sign, off / 3600 , off / 60 % 60 )
435451 }
436452 } else {
437- write ! ( w, "Z" )
453+ result. push_str ( "Z" ) ;
454+ Ok ( ( ) )
438455 }
439456 }
440457
441458 let ret = match spec {
442459 ShortMonthName =>
443- date. map ( |d| write ! ( w, "{}" , SHORT_MONTHS [ d. month0( ) as usize ] ) ) ,
460+ date. map ( |d| {
461+ result. push_str ( SHORT_MONTHS [ d. month0 ( ) as usize ] ) ;
462+ Ok ( ( ) )
463+ } ) ,
444464 LongMonthName =>
445- date. map ( |d| write ! ( w, "{}" , LONG_MONTHS [ d. month0( ) as usize ] ) ) ,
465+ date. map ( |d| {
466+ result. push_str ( LONG_MONTHS [ d. month0 ( ) as usize ] ) ;
467+ Ok ( ( ) )
468+ } ) ,
446469 ShortWeekdayName =>
447- date. map ( |d| write ! ( w, "{}" ,
448- SHORT_WEEKDAYS [ d. weekday( ) . num_days_from_monday( ) as usize ] ) ) ,
470+ date. map ( |d| {
471+ result. push_str (
472+ SHORT_WEEKDAYS [ d. weekday ( ) . num_days_from_monday ( ) as usize ]
473+ ) ;
474+ Ok ( ( ) )
475+ } ) ,
449476 LongWeekdayName =>
450- date. map ( |d| write ! ( w, "{}" ,
451- LONG_WEEKDAYS [ d. weekday( ) . num_days_from_monday( ) as usize ] ) ) ,
477+ date. map ( |d| {
478+ result. push_str (
479+ LONG_WEEKDAYS [ d. weekday ( ) . num_days_from_monday ( ) as usize ]
480+ ) ;
481+ Ok ( ( ) )
482+ } ) ,
452483 LowerAmPm =>
453- time. map ( |t| write ! ( w, "{}" , if t. hour12( ) . 0 { "pm" } else { "am" } ) ) ,
484+ time. map ( |t| {
485+ result. push_str ( if t. hour12 ( ) . 0 { "pm" } else { "am" } ) ;
486+ Ok ( ( ) )
487+ } ) ,
454488 UpperAmPm =>
455- time. map ( |t| write ! ( w, "{}" , if t. hour12( ) . 0 { "PM" } else { "AM" } ) ) ,
489+ time. map ( |t| {
490+ result. push_str ( if t. hour12 ( ) . 0 { "PM" } else { "AM" } ) ;
491+ Ok ( ( ) )
492+ } ) ,
456493 Nanosecond =>
457494 time. map ( |t| {
458495 let nano = t. nanosecond ( ) % 1_000_000_000 ;
459496 if nano == 0 {
460497 Ok ( ( ) )
461498 } else if nano % 1_000_000 == 0 {
462- write ! ( w , ".{:03}" , nano / 1_000_000 )
499+ write ! ( result , ".{:03}" , nano / 1_000_000 )
463500 } else if nano % 1_000 == 0 {
464- write ! ( w , ".{:06}" , nano / 1_000 )
501+ write ! ( result , ".{:06}" , nano / 1_000 )
465502 } else {
466- write ! ( w , ".{:09}" , nano)
503+ write ! ( result , ".{:09}" , nano)
467504 }
468505 } ) ,
469506 Nanosecond3 =>
470507 time. map ( |t| {
471508 let nano = t. nanosecond ( ) % 1_000_000_000 ;
472- write ! ( w , ".{:03}" , nano / 1_000_000 )
509+ write ! ( result , ".{:03}" , nano / 1_000_000 )
473510 } ) ,
474511 Nanosecond6 =>
475512 time. map ( |t| {
476513 let nano = t. nanosecond ( ) % 1_000_000_000 ;
477- write ! ( w , ".{:06}" , nano / 1_000 )
514+ write ! ( result , ".{:06}" , nano / 1_000 )
478515 } ) ,
479516 Nanosecond9 =>
480517 time. map ( |t| {
481518 let nano = t. nanosecond ( ) % 1_000_000_000 ;
482- write ! ( w , ".{:09}" , nano)
519+ write ! ( result , ".{:09}" , nano)
483520 } ) ,
484521 Internal ( InternalFixed { val : InternalInternal :: Nanosecond3NoDot } ) =>
485522 time. map ( |t| {
486523 let nano = t. nanosecond ( ) % 1_000_000_000 ;
487- write ! ( w , "{:03}" , nano / 1_000_000 )
524+ write ! ( result , "{:03}" , nano / 1_000_000 )
488525 } ) ,
489526 Internal ( InternalFixed { val : InternalInternal :: Nanosecond6NoDot } ) =>
490527 time. map ( |t| {
491528 let nano = t. nanosecond ( ) % 1_000_000_000 ;
492- write ! ( w , "{:06}" , nano / 1_000 )
529+ write ! ( result , "{:06}" , nano / 1_000 )
493530 } ) ,
494531 Internal ( InternalFixed { val : InternalInternal :: Nanosecond9NoDot } ) =>
495532 time. map ( |t| {
496533 let nano = t. nanosecond ( ) % 1_000_000_000 ;
497- write ! ( w , "{:09}" , nano)
534+ write ! ( result , "{:09}" , nano)
498535 } ) ,
499536 TimezoneName =>
500- off. map ( |& ( ref name, _) | write ! ( w, "{}" , * name) ) ,
537+ off. map ( |& ( ref name, _) | {
538+ result. push_str ( name) ;
539+ Ok ( ( ) )
540+ } ) ,
501541 TimezoneOffsetColon =>
502- off. map ( |& ( _, off) | write_local_minus_utc ( w , off, false , true ) ) ,
542+ off. map ( |& ( _, off) | write_local_minus_utc ( & mut result , off, false , true ) ) ,
503543 TimezoneOffsetColonZ =>
504- off. map ( |& ( _, off) | write_local_minus_utc ( w , off, true , true ) ) ,
544+ off. map ( |& ( _, off) | write_local_minus_utc ( & mut result , off, true , true ) ) ,
505545 TimezoneOffset =>
506- off. map ( |& ( _, off) | write_local_minus_utc ( w , off, false , false ) ) ,
546+ off. map ( |& ( _, off) | write_local_minus_utc ( & mut result , off, false , false ) ) ,
507547 TimezoneOffsetZ =>
508- off. map ( |& ( _, off) | write_local_minus_utc ( w , off, true , false ) ) ,
548+ off. map ( |& ( _, off) | write_local_minus_utc ( & mut result , off, true , false ) ) ,
509549 Internal ( InternalFixed { val : InternalInternal :: TimezoneOffsetPermissive } ) =>
510550 panic ! ( "Do not try to write %#z it is undefined" ) ,
511551 RFC2822 => // same to `%a, %e %b %Y %H:%M:%S %z`
512552 if let ( Some ( d) , Some ( t) , Some ( & ( _, off) ) ) = ( date, time, off) {
513553 let sec = t. second ( ) + t. nanosecond ( ) / 1_000_000_000 ;
514- try!( write ! ( w, "{}, {:2} {} {:04} {:02}:{:02}:{:02} " ,
515- SHORT_WEEKDAYS [ d. weekday( ) . num_days_from_monday( ) as usize ] ,
516- d. day( ) , SHORT_MONTHS [ d. month0( ) as usize ] , d. year( ) ,
517- t. hour( ) , t. minute( ) , sec) ) ;
518- Some ( write_local_minus_utc ( w, off, false , false ) )
554+ try!( write ! (
555+ result,
556+ "{}, {:2} {} {:04} {:02}:{:02}:{:02} " ,
557+ SHORT_WEEKDAYS [ d. weekday( ) . num_days_from_monday( ) as usize ] ,
558+ d. day( ) , SHORT_MONTHS [ d. month0( ) as usize ] , d. year( ) ,
559+ t. hour( ) , t. minute( ) , sec
560+ ) ) ;
561+ Some ( write_local_minus_utc ( & mut result, off, false , false ) )
519562 } else {
520563 None
521564 } ,
522565 RFC3339 => // same to `%Y-%m-%dT%H:%M:%S%.f%:z`
523566 if let ( Some ( d) , Some ( t) , Some ( & ( _, off) ) ) = ( date, time, off) {
524567 // reuse `Debug` impls which already print ISO 8601 format.
525568 // this is faster in this way.
526- try!( write ! ( w , "{:?}T{:?}" , d, t) ) ;
527- Some ( write_local_minus_utc ( w , off, false , true ) )
569+ try!( write ! ( result , "{:?}T{:?}" , d, t) ) ;
570+ Some ( write_local_minus_utc ( & mut result , off, false , true ) )
528571 } else {
529572 None
530573 } ,
@@ -540,7 +583,7 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
540583 }
541584 }
542585
543- Ok ( ( ) )
586+ w . pad ( & result )
544587}
545588
546589mod parsed;
0 commit comments