@@ -21,12 +21,26 @@ use crate::roc::Roc;
21
21
use crate :: { types, AsCalendar , Calendar , Date , DateDuration , DateDurationUnit , DateTime , Ref } ;
22
22
23
23
use icu_locale_core:: extensions:: unicode:: { key, value, Value } ;
24
+ use icu_locale_core:: preferences:: define_preferences;
25
+ use icu_locale_core:: preferences:: extensions:: unicode:: keywords:: {
26
+ CalendarAlgorithm , IslamicCalendarAlgorithm ,
27
+ } ;
24
28
use icu_locale_core:: subtags:: language;
25
29
use icu_locale_core:: Locale ;
26
30
use icu_provider:: prelude:: * ;
27
31
28
32
use core:: fmt;
29
33
34
+ define_preferences ! (
35
+ /// The prefs for datetime formatting.
36
+ [ Copy ]
37
+ AnyCalendarPreferences ,
38
+ {
39
+ /// The user's preferred calendar system.
40
+ calendar_algorithm: CalendarAlgorithm
41
+ }
42
+ ) ;
43
+
30
44
/// This is a calendar that encompasses all formattable calendars supported by this crate
31
45
///
32
46
/// This allows for the construction of [`Date`] objects that have their calendar known at runtime.
@@ -46,7 +60,7 @@ use core::fmt;
46
60
///
47
61
/// let locale = locale!("en-u-ca-japanese"); // English with the Japanese calendar
48
62
///
49
- /// let calendar = AnyCalendar::new_for_locale(& locale.into());
63
+ /// let calendar = AnyCalendar::new_for_locale(locale.into());
50
64
/// let calendar = Rc::new(calendar); // Avoid cloning it each time
51
65
/// // If everything is a local reference, you may use icu::calendar::Ref instead.
52
66
///
@@ -748,13 +762,13 @@ impl AnyCalendar {
748
762
///
749
763
/// [📚 Help choosing a constructor](icu_provider::constructors)
750
764
#[ cfg( feature = "compiled_data" ) ]
751
- pub fn new_for_locale ( locale : & DataLocale ) -> Self {
752
- let kind = AnyCalendarKind :: from_data_locale_with_fallback ( locale ) ;
765
+ pub fn new_for_locale ( prefs : AnyCalendarPreferences ) -> Self {
766
+ let kind = AnyCalendarKind :: from_prefs_with_fallback ( prefs ) ;
753
767
Self :: new ( kind)
754
768
}
755
769
756
770
icu_provider:: gen_any_buffer_data_constructors!(
757
- ( locale ) -> error: DataError ,
771
+ ( prefs : AnyCalendarPreferences ) -> error: DataError ,
758
772
functions: [
759
773
new_for_locale: skip,
760
774
try_new_for_locale_with_any_provider,
@@ -767,7 +781,7 @@ impl AnyCalendar {
767
781
#[ doc = icu_provider:: gen_any_buffer_unstable_docs!( UNSTABLE , Self :: new_for_locale) ]
768
782
pub fn try_new_for_locale_unstable < P > (
769
783
provider : & P ,
770
- locale : & DataLocale ,
784
+ prefs : AnyCalendarPreferences ,
771
785
) -> Result < Self , DataError >
772
786
where
773
787
P : DataProvider < crate :: provider:: JapaneseErasV1Marker >
@@ -778,7 +792,7 @@ impl AnyCalendar {
778
792
+ DataProvider < crate :: provider:: IslamicUmmAlQuraCacheV1Marker >
779
793
+ ?Sized ,
780
794
{
781
- let kind = AnyCalendarKind :: from_data_locale_with_fallback ( locale ) ;
795
+ let kind = AnyCalendarKind :: from_prefs_with_fallback ( prefs ) ;
782
796
Self :: try_new_unstable ( provider, kind)
783
797
}
784
798
@@ -1028,6 +1042,40 @@ impl AnyCalendarKind {
1028
1042
}
1029
1043
}
1030
1044
1045
+ fn get_for_preferences_calendar ( pcal : CalendarAlgorithm ) -> Option < Self > {
1046
+ match pcal {
1047
+ CalendarAlgorithm :: Buddhist => Some ( Self :: Buddhist ) ,
1048
+ CalendarAlgorithm :: Chinese => Some ( Self :: Chinese ) ,
1049
+ CalendarAlgorithm :: Coptic => Some ( Self :: Coptic ) ,
1050
+ CalendarAlgorithm :: Dangi => Some ( Self :: Dangi ) ,
1051
+ CalendarAlgorithm :: Ethioaa => Some ( Self :: EthiopianAmeteAlem ) ,
1052
+ CalendarAlgorithm :: Ethiopic => Some ( Self :: Ethiopian ) ,
1053
+ CalendarAlgorithm :: Gregory => Some ( Self :: Gregorian ) ,
1054
+ CalendarAlgorithm :: Hebrew => Some ( Self :: Hebrew ) ,
1055
+ CalendarAlgorithm :: Indian => Some ( Self :: Indian ) ,
1056
+ CalendarAlgorithm :: Islamic ( None ) => Some ( Self :: IslamicObservational ) ,
1057
+ CalendarAlgorithm :: Islamic ( Some ( islamic) ) => match islamic {
1058
+ IslamicCalendarAlgorithm :: Umalqura => Some ( Self :: IslamicUmmAlQura ) ,
1059
+ IslamicCalendarAlgorithm :: Tbla => Some ( Self :: IslamicTabular ) ,
1060
+ IslamicCalendarAlgorithm :: Civil => Some ( Self :: IslamicCivil ) ,
1061
+ // Rgsa is not supported
1062
+ IslamicCalendarAlgorithm :: Rgsa => None ,
1063
+ _ => {
1064
+ debug_assert ! ( false , "unknown calendar algorithm {pcal:?}" ) ;
1065
+ None
1066
+ }
1067
+ } ,
1068
+ CalendarAlgorithm :: Iso8601 => Some ( Self :: Iso ) ,
1069
+ CalendarAlgorithm :: Japanese => Some ( Self :: Japanese ) ,
1070
+ CalendarAlgorithm :: Persian => Some ( Self :: Persian ) ,
1071
+ CalendarAlgorithm :: Roc => Some ( Self :: Roc ) ,
1072
+ _ => {
1073
+ debug_assert ! ( false , "unknown calendar algorithm {pcal:?}" ) ;
1074
+ None
1075
+ }
1076
+ }
1077
+ }
1078
+
1031
1079
fn debug_name ( self ) -> & ' static str {
1032
1080
match self {
1033
1081
AnyCalendarKind :: Buddhist => Buddhist . debug_name ( ) ,
@@ -1062,21 +1110,22 @@ impl AnyCalendarKind {
1062
1110
. and_then ( Self :: get_for_bcp47_value)
1063
1111
}
1064
1112
1065
- /// Extract the calendar component from a [`DataLocale `]
1113
+ /// Extract the calendar component from a [`AnyCalendarPreferences `]
1066
1114
///
1067
1115
/// Returns `None` if the calendar is not specified or unknown.
1068
- fn get_for_data_locale ( l : & DataLocale ) -> Option < Self > {
1069
- l. get_unicode_ext ( & key ! ( "ca" ) )
1070
- . and_then ( |v| Self :: get_for_bcp47_value ( & v) )
1116
+ fn get_for_prefs ( prefs : AnyCalendarPreferences ) -> Option < Self > {
1117
+ prefs
1118
+ . calendar_algorithm
1119
+ . and_then ( Self :: get_for_preferences_calendar)
1071
1120
}
1072
1121
1073
1122
// Do not make public, this will eventually need fallback
1074
1123
// data from the provider
1075
- fn from_data_locale_with_fallback ( l : & DataLocale ) -> Self {
1076
- if let Some ( kind) = Self :: get_for_data_locale ( l ) {
1124
+ fn from_prefs_with_fallback ( prefs : AnyCalendarPreferences ) -> Self {
1125
+ if let Some ( kind) = Self :: get_for_prefs ( prefs ) {
1077
1126
kind
1078
1127
} else {
1079
- let lang = l . language ;
1128
+ let lang = prefs . locale_prefs . language ;
1080
1129
if lang == language ! ( "th" ) {
1081
1130
Self :: Buddhist
1082
1131
} else if lang == language ! ( "sa" ) {
0 commit comments