@@ -12,10 +12,7 @@ use crate::provider::date_time::{
1212 MonthPlaceholderValue , TimeSymbols , ZoneSymbols ,
1313} ;
1414use crate :: time_zone:: {
15- Bcp47IdFormat , ExemplarCityFormat , FallbackTimeZoneFormatterUnit , FormatTimeZone ,
16- FormatTimeZoneError , GenericLocationFormat , GenericNonLocationLongFormat ,
17- GenericNonLocationShortFormat , Iso8601Format , LocalizedOffsetFormat ,
18- SpecificNonLocationLongFormat , SpecificNonLocationShortFormat , TimeZoneDataPayloadsBorrowed ,
15+ FormatTimeZone , FormatTimeZoneError , Iso8601Format , TimeZoneDataPayloadsBorrowed ,
1916 TimeZoneFormatterUnit ,
2017} ;
2118use crate :: time_zone:: { IsoFormat , IsoMinutes , IsoSeconds , ResolvedNeoTimeZoneSkeleton } ;
@@ -658,7 +655,7 @@ pub(crate) fn try_write_zone<'data, W, ZS>(
658655 field_length : FieldLength ,
659656 input : & ExtractedInput ,
660657 zone_symbols : Option < & ZS > ,
661- _fdf : Option < & FixedDecimalFormatter > ,
658+ fdf : Option < & FixedDecimalFormatter > ,
662659 w : & mut W ,
663660) -> Result < Result < ( ) , DateTimeWriteError > , fmt:: Error >
664661where
@@ -671,7 +668,12 @@ where
671668 ) -> fmt:: Result {
672669 match offset {
673670 Some ( offset) => w. with_part ( Part :: ERROR , |w| {
674- Iso8601Format :: default_for_fallback ( ) . format_infallible ( w, offset)
671+ Iso8601Format {
672+ format : IsoFormat :: Basic ,
673+ minutes : IsoMinutes :: Required ,
674+ seconds : IsoSeconds :: Optional ,
675+ }
676+ . format_infallible ( w, offset)
675677 } ) ,
676678 None => w. with_part ( Part :: ERROR , |w| "{GMT+?}" . write_to ( w) ) ,
677679 }
@@ -697,7 +699,7 @@ where
697699 Some ( time_zone) => {
698700 let payloads = zs. get_payloads ( ) ;
699701 let units = select_zone_units ( time_zone) ;
700- match do_write_zone ( units, input, payloads, w) ? {
702+ match do_write_zone ( units, input, payloads, fdf , w) ? {
701703 Ok ( ( ) ) => Ok ( ( ) ) ,
702704 Err ( ( ) ) => {
703705 write_time_zone_missing ( input. offset , w) ?;
@@ -712,193 +714,175 @@ where
712714
713715/// Given a [`ResolvedNeoTimeZoneSkeleton`], select the formatter units
714716fn select_zone_units ( time_zone : ResolvedNeoTimeZoneSkeleton ) -> [ Option < TimeZoneFormatterUnit > ; 3 ] {
715- // Select which formatters to try based on the field.
716- let mut formatters = (
717- None ,
718- None ,
719- // Friendly Localized offset Format (requires "essentials" data)
720- Some ( TimeZoneFormatterUnit :: WithFallback (
721- FallbackTimeZoneFormatterUnit :: LocalizedOffset ( LocalizedOffsetFormat { } ) ,
722- ) ) ,
723- ) ;
724717 match time_zone {
725718 // `z..zzz`
726- ResolvedNeoTimeZoneSkeleton :: SpecificShort => {
727- formatters . 0 = Some ( TimeZoneFormatterUnit :: SpecificNonLocationShort (
728- SpecificNonLocationShortFormat { } ,
729- ) ) ;
730- }
719+ ResolvedNeoTimeZoneSkeleton :: SpecificShort => [
720+ Some ( TimeZoneFormatterUnit :: SpecificNonLocationShort ) ,
721+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetShort ) ,
722+ None ,
723+ ] ,
731724 // `zzzz`
732- ResolvedNeoTimeZoneSkeleton :: SpecificLong => {
733- formatters . 0 = Some ( TimeZoneFormatterUnit :: SpecificNonLocationLong (
734- SpecificNonLocationLongFormat { } ,
735- ) ) ;
736- }
725+ ResolvedNeoTimeZoneSkeleton :: SpecificLong => [
726+ Some ( TimeZoneFormatterUnit :: SpecificNonLocationLong ) ,
727+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) ,
728+ None ,
729+ ] ,
737730 // 'v'
738- ResolvedNeoTimeZoneSkeleton :: GenericShort => {
739- formatters. 0 = Some ( TimeZoneFormatterUnit :: GenericNonLocationShort (
740- GenericNonLocationShortFormat { } ,
741- ) ) ;
742- formatters. 1 = Some ( TimeZoneFormatterUnit :: GenericLocation (
743- GenericLocationFormat { } ,
744- ) ) ;
745- }
731+ ResolvedNeoTimeZoneSkeleton :: GenericShort => [
732+ Some ( TimeZoneFormatterUnit :: GenericNonLocationShort ) ,
733+ Some ( TimeZoneFormatterUnit :: GenericLocation ) ,
734+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetShort ) ,
735+ ] ,
746736 // 'vvvv'
747- ResolvedNeoTimeZoneSkeleton :: GenericLong => {
748- formatters. 0 = Some ( TimeZoneFormatterUnit :: GenericNonLocationLong (
749- GenericNonLocationLongFormat { } ,
750- ) ) ;
751- formatters. 1 = Some ( TimeZoneFormatterUnit :: GenericLocation (
752- GenericLocationFormat { } ,
753- ) ) ;
754- }
737+ ResolvedNeoTimeZoneSkeleton :: GenericLong => [
738+ Some ( TimeZoneFormatterUnit :: GenericNonLocationLong ) ,
739+ Some ( TimeZoneFormatterUnit :: GenericLocation ) ,
740+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) ,
741+ ] ,
755742 // 'VVV'
756- ResolvedNeoTimeZoneSkeleton :: City => {
757- formatters. 0 = Some ( TimeZoneFormatterUnit :: ExemplarCity ( ExemplarCityFormat { } ) ) ;
758- }
743+ ResolvedNeoTimeZoneSkeleton :: City => [
744+ Some ( TimeZoneFormatterUnit :: ExemplarCity ) ,
745+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) ,
746+ None ,
747+ ] ,
759748 // 'VVVV'
760- ResolvedNeoTimeZoneSkeleton :: Location => {
761- formatters. 0 = Some ( TimeZoneFormatterUnit :: GenericLocation (
762- GenericLocationFormat { } ,
763- ) ) ;
764- }
765- // `O`
766- ResolvedNeoTimeZoneSkeleton :: OffsetShort => {
767- // TODO: For now, use the long format. This should be GMT-8
768- }
769- // `OOOO`, `ZZZZ`
749+ ResolvedNeoTimeZoneSkeleton :: Location => [
750+ Some ( TimeZoneFormatterUnit :: GenericLocation ) ,
751+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) ,
752+ None ,
753+ ] ,
754+ // `O`, `ZZZZ`
755+ ResolvedNeoTimeZoneSkeleton :: OffsetShort => [
756+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetShort ) ,
757+ None ,
758+ None ,
759+ ] ,
760+ // `OOOO`
770761 ResolvedNeoTimeZoneSkeleton :: OffsetLong => {
771- // no-op
762+ [ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) , None , None ]
772763 }
773764 // 'V'
774- ResolvedNeoTimeZoneSkeleton :: Bcp47Id => {
775- formatters. 0 = Some ( TimeZoneFormatterUnit :: Bcp47Id ( Bcp47IdFormat { } ) ) ;
776- }
765+ ResolvedNeoTimeZoneSkeleton :: Bcp47Id => [
766+ Some ( TimeZoneFormatterUnit :: Bcp47Id ) ,
767+ Some ( TimeZoneFormatterUnit :: LocalizedOffsetLong ) ,
768+ None ,
769+ ] ,
777770 // 'X'
778- ResolvedNeoTimeZoneSkeleton :: IsoX => {
779- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
780- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
781- format : IsoFormat :: UtcBasic ,
782- minutes : IsoMinutes :: Optional ,
783- seconds : IsoSeconds :: Never ,
784- } ) ,
785- ) ) ;
786- }
771+ ResolvedNeoTimeZoneSkeleton :: IsoX => [
772+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
773+ format : IsoFormat :: UtcBasic ,
774+ minutes : IsoMinutes :: Optional ,
775+ seconds : IsoSeconds :: Never ,
776+ } ) ) ,
777+ None ,
778+ None ,
779+ ] ,
787780 // 'XX'
788- ResolvedNeoTimeZoneSkeleton :: IsoXX => {
789- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
790- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
791- format : IsoFormat :: UtcBasic ,
792- minutes : IsoMinutes :: Required ,
793- seconds : IsoSeconds :: Never ,
794- } ) ,
795- ) ) ;
796- }
781+ ResolvedNeoTimeZoneSkeleton :: IsoXX => [
782+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
783+ format : IsoFormat :: UtcBasic ,
784+ minutes : IsoMinutes :: Required ,
785+ seconds : IsoSeconds :: Never ,
786+ } ) ) ,
787+ None ,
788+ None ,
789+ ] ,
797790 // 'XXX'
798- ResolvedNeoTimeZoneSkeleton :: IsoXXX => {
799- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
800- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
801- format : IsoFormat :: UtcExtended ,
802- minutes : IsoMinutes :: Required ,
803- seconds : IsoSeconds :: Never ,
804- } ) ,
805- ) ) ;
806- }
791+ ResolvedNeoTimeZoneSkeleton :: IsoXXX => [
792+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
793+ format : IsoFormat :: UtcExtended ,
794+ minutes : IsoMinutes :: Required ,
795+ seconds : IsoSeconds :: Never ,
796+ } ) ) ,
797+ None ,
798+ None ,
799+ ] ,
807800 // 'XXXX'
808- ResolvedNeoTimeZoneSkeleton :: IsoXXXX => {
809- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
810- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
811- format : IsoFormat :: UtcBasic ,
812- minutes : IsoMinutes :: Required ,
813- seconds : IsoSeconds :: Optional ,
814- } ) ,
815- ) ) ;
816- }
801+ ResolvedNeoTimeZoneSkeleton :: IsoXXXX => [
802+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
803+ format : IsoFormat :: UtcBasic ,
804+ minutes : IsoMinutes :: Required ,
805+ seconds : IsoSeconds :: Optional ,
806+ } ) ) ,
807+ None ,
808+ None ,
809+ ] ,
817810 // 'XXXXX', 'ZZZZZ'
818- ResolvedNeoTimeZoneSkeleton :: IsoXXXXX => {
819- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
820- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
821- format : IsoFormat :: UtcExtended ,
822- minutes : IsoMinutes :: Required ,
823- seconds : IsoSeconds :: Optional ,
824- } ) ,
825- ) ) ;
826- }
811+ ResolvedNeoTimeZoneSkeleton :: IsoXXXXX => [
812+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
813+ format : IsoFormat :: UtcExtended ,
814+ minutes : IsoMinutes :: Required ,
815+ seconds : IsoSeconds :: Optional ,
816+ } ) ) ,
817+ None ,
818+ None ,
819+ ] ,
827820 // 'x'
828- ResolvedNeoTimeZoneSkeleton :: Isox => {
829- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
830- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
831- format : IsoFormat :: Basic ,
832- minutes : IsoMinutes :: Optional ,
833- seconds : IsoSeconds :: Never ,
834- } ) ,
835- ) ) ;
836- }
821+ ResolvedNeoTimeZoneSkeleton :: Isox => [
822+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
823+ format : IsoFormat :: Basic ,
824+ minutes : IsoMinutes :: Optional ,
825+ seconds : IsoSeconds :: Never ,
826+ } ) ) ,
827+ None ,
828+ None ,
829+ ] ,
837830 // 'xx'
838- ResolvedNeoTimeZoneSkeleton :: Isoxx => {
839- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
840- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
841- format : IsoFormat :: Basic ,
842- minutes : IsoMinutes :: Required ,
843- seconds : IsoSeconds :: Never ,
844- } ) ,
845- ) ) ;
846- }
831+ ResolvedNeoTimeZoneSkeleton :: Isoxx => [
832+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
833+ format : IsoFormat :: Basic ,
834+ minutes : IsoMinutes :: Required ,
835+ seconds : IsoSeconds :: Never ,
836+ } ) ) ,
837+ None ,
838+ None ,
839+ ] ,
847840 // 'xxx'
848- ResolvedNeoTimeZoneSkeleton :: Isoxxx => {
849- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
850- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
851- format : IsoFormat :: Extended ,
852- minutes : IsoMinutes :: Required ,
853- seconds : IsoSeconds :: Never ,
854- } ) ,
855- ) ) ;
856- }
841+ ResolvedNeoTimeZoneSkeleton :: Isoxxx => [
842+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
843+ format : IsoFormat :: Extended ,
844+ minutes : IsoMinutes :: Required ,
845+ seconds : IsoSeconds :: Never ,
846+ } ) ) ,
847+ None ,
848+ None ,
849+ ] ,
857850 // 'xxxx', 'Z', 'ZZ', 'ZZZ'
858- ResolvedNeoTimeZoneSkeleton :: Isoxxxx => {
859- formatters . 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
860- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
861- format : IsoFormat :: Basic ,
862- minutes : IsoMinutes :: Required ,
863- seconds : IsoSeconds :: Optional ,
864- } ) ,
865- ) ) ;
866- }
851+ ResolvedNeoTimeZoneSkeleton :: Isoxxxx => [
852+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
853+ format : IsoFormat :: Basic ,
854+ minutes : IsoMinutes :: Required ,
855+ seconds : IsoSeconds :: Optional ,
856+ } ) ) ,
857+ None ,
858+ None ,
859+ ] ,
867860 // 'xxxxx', 'ZZZZZ'
868- ResolvedNeoTimeZoneSkeleton :: Isoxxxxx => {
869- formatters. 2 = Some ( TimeZoneFormatterUnit :: WithFallback (
870- FallbackTimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
871- format : IsoFormat :: Extended ,
872- minutes : IsoMinutes :: Required ,
873- seconds : IsoSeconds :: Optional ,
874- } ) ,
875- ) ) ;
876- }
877- } ;
878- // TODO:
879- // `VV` "America/Los_Angeles"
880- // Generic Partial Location: "Pacific Time (Los Angeles)"
881- // All `x` and `X` formats
882- [ formatters. 0 , formatters. 1 , formatters. 2 ]
861+ ResolvedNeoTimeZoneSkeleton :: Isoxxxxx => [
862+ Some ( TimeZoneFormatterUnit :: Iso8601 ( Iso8601Format {
863+ format : IsoFormat :: Extended ,
864+ minutes : IsoMinutes :: Required ,
865+ seconds : IsoSeconds :: Optional ,
866+ } ) ) ,
867+ None ,
868+ None ,
869+ ] ,
870+ }
883871}
884872
885873/// Perform the formatting given all of the resolved parameters
886874fn do_write_zone < W > (
887875 units : [ Option < TimeZoneFormatterUnit > ; 3 ] ,
888876 input : & ExtractedInput ,
889877 payloads : TimeZoneDataPayloadsBorrowed ,
878+ fdf : Option < & FixedDecimalFormatter > ,
890879 w : & mut W ,
891880) -> Result < Result < ( ) , ( ) > , fmt:: Error >
892881where
893882 W : writeable:: PartsWrite + ?Sized ,
894883{
895- let [ mut f0, mut f1, mut f2] = units;
896- Ok ( loop {
897- let Some ( formatter) = f0. take ( ) . or_else ( || f1. take ( ) ) . or_else ( || f2. take ( ) ) else {
898- break Err ( ( ) ) ;
899- } ;
900- match formatter. format ( w, input, payloads) ? {
901- Ok ( ( ) ) => break Ok ( ( ) ) ,
884+ for formatter in units. into_iter ( ) . flatten ( ) {
885+ match formatter. format ( w, input, payloads, fdf) ? {
902886 Err ( FormatTimeZoneError :: MissingInputField ( _) ) => {
903887 // The time zone input doesn't have the fields for this formatter.
904888 // TODO: What behavior makes the most sense here?
@@ -916,8 +900,17 @@ where
916900 // We can keep trying other formatters.
917901 continue ;
918902 }
903+ Err ( FormatTimeZoneError :: MissingFixedDecimalFormatter ) => {
904+ // We don't have the necessary data for this formatter.
905+ // TODO: What behavior makes the most sense here?
906+ // We can keep trying other formatters.
907+ continue ;
908+ }
909+ Ok ( ( ) ) => return Ok ( Ok ( ( ) ) ) ,
919910 }
920- } )
911+ }
912+
913+ Ok ( Err ( ( ) ) )
921914}
922915
923916#[ cfg( test) ]
0 commit comments