From 354c9999ea80695d1df2cdd011f73425a1148fa3 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 22 Nov 2024 16:08:47 -0800 Subject: [PATCH] Make GetField sealed; other datetime docs fixes --- components/datetime/src/fieldsets.rs | 26 +++++++++++++- components/datetime/src/neo.rs | 23 +++++++++++- components/datetime/src/scaffold/calendar.rs | 2 +- .../datetime/src/scaffold/dynamic_impls.rs | 2 ++ .../datetime/src/scaffold/fieldset_traits.rs | 35 ++++++++++++++++++- components/datetime/src/scaffold/get_field.rs | 20 +++++++++-- 6 files changed, 102 insertions(+), 6 deletions(-) diff --git a/components/datetime/src/fieldsets.rs b/components/datetime/src/fieldsets.rs index 831af7e4531..c49851cd131 100644 --- a/components/datetime/src/fieldsets.rs +++ b/components/datetime/src/fieldsets.rs @@ -7,6 +7,27 @@ //! Each field set is a struct containing options specified to that field set. //! The fields can either be set directly or via helper functions. //! +//! This module contains _static_ field sets, which deliver the smallest binary size. +//! If the field set is not known until runtime, use a _dynamic_ field set: [`enums`] +//! +//! # What is a Field Set? +//! +//! A field set determines what datetime fields should be printed in the localized output. +//! +//! Examples of field sets include: +//! +//! 1. Year, month, and day ([`YMD`]) +//! 2. Weekday and time ([`ET`]) +//! +//! Field sets fit into four categories: +//! +//! 1. Date: fields that specify a particular day in time. +//! 2. Calendar period: fields that specify a span of time greater than a day. +//! 3. Time: fields that specify a time within a day. +//! 4. Zone: fields that specify a time zone or offset from UTC. +//! +//! Certain combinations of field sets are allowed, too. See [`Combo`]. +//! //! # Examples //! //! Two ways to configure the same field set: @@ -1098,7 +1119,8 @@ impl_calendar_period_marker!( ); impl_time_marker!( - /// Hours can be switched between 12-hour and 24-hour time via the `u-hc` locale keyword. + /// Hours can be switched between 12-hour and 24-hour time via the `u-hc` locale keyword + /// or [`DateTimeFormatterPreferences`]. /// /// ``` /// use icu::calendar::Time; @@ -1182,6 +1204,8 @@ impl_time_marker!( /// "24:00" /// ); /// ``` + /// + /// [`DateTimeFormatterPreferences`]: crate::DateTimeFormatterPreferences T, description = "time (locale-dependent hour cycle)", sample_length = medium, diff --git a/components/datetime/src/neo.rs b/components/datetime/src/neo.rs index a4684e583c1..69876da67f6 100644 --- a/components/datetime/src/neo.rs +++ b/components/datetime/src/neo.rs @@ -32,7 +32,28 @@ use icu_provider::prelude::*; use writeable::TryWriteable; define_preferences!( - /// The prefs for datetime formatting. + /// The user locale preferences for datetime formatting. + /// + /// # Examples + /// + /// Two ways to build a preferences bag with a custom hour cycle and calendar system: + /// + /// ``` + /// use icu::datetime::DateTimeFormatterPreferences; + /// use icu::locale::Locale; + /// use icu::locale::preferences::extensions::unicode::keywords::CalendarAlgorithm; + /// use icu::locale::preferences::extensions::unicode::keywords::HourCycle; + /// use icu::locale::subtags::Language; + /// + /// let prefs1: DateTimeFormatterPreferences = Locale::try_from_str("fr-u-ca-buddhist-hc-h12").unwrap().into(); + /// + /// let mut prefs2 = DateTimeFormatterPreferences::default(); + /// prefs2.locale_prefs.language = Language::try_from_str("fr").unwrap(); + /// prefs2.hour_cycle = Some(HourCycle::H12); + /// prefs2.calendar_algorithm = Some(CalendarAlgorithm::Buddhist); + /// + /// assert_eq!(prefs1, prefs2); + /// ``` [Copy] DateTimeFormatterPreferences, { diff --git a/components/datetime/src/scaffold/calendar.rs b/components/datetime/src/scaffold/calendar.rs index c68e74b43e0..3886a73a15e 100644 --- a/components/datetime/src/scaffold/calendar.rs +++ b/components/datetime/src/scaffold/calendar.rs @@ -22,7 +22,7 @@ use icu_provider::marker::NeverMarker; use icu_provider::prelude::*; use icu_timezone::{CustomZonedDateTime, TimeZoneInfo, TimeZoneModel, UtcOffset}; -/// A calendar that can be found in CLDR +/// A calendar that can be found in CLDR. /// /// New implementors of this trait will likely also wish to modify `get_era_code_map()` /// in the CLDR transformer to support any new era maps. diff --git a/components/datetime/src/scaffold/dynamic_impls.rs b/components/datetime/src/scaffold/dynamic_impls.rs index 58f0db5d777..eb86647bd4e 100644 --- a/components/datetime/src/scaffold/dynamic_impls.rs +++ b/components/datetime/src/scaffold/dynamic_impls.rs @@ -137,6 +137,8 @@ impl DateTimeMarkers for TimeFieldSet { type GluePatternV1Marker = datetime_marker_helper!(@glue,); } +impl UnstableSealed for DateAndTimeFieldSet {} + impl UnstableSealed for ZoneFieldSet {} impl DateTimeNamesMarker for ZoneFieldSet { diff --git a/components/datetime/src/scaffold/fieldset_traits.rs b/components/datetime/src/scaffold/fieldset_traits.rs index 9848c9175c0..bb0f46fefac 100644 --- a/components/datetime/src/scaffold/fieldset_traits.rs +++ b/components/datetime/src/scaffold/fieldset_traits.rs @@ -26,6 +26,8 @@ use icu_timezone::{TimeZoneBcp47Id, UtcOffset, ZoneVariant}; /// A trait associating types for date formatting in any calendar /// (input types only). +/// +/// This is a sealed trait implemented on field set markers. pub trait DateInputMarkers: UnstableSealed { /// Marker for resolving the year input field. type YearInput: IntoOption; @@ -41,6 +43,8 @@ pub trait DateInputMarkers: UnstableSealed { /// A trait associating types for date formatting in a specific calendar /// (data markers only). +/// +/// This is a sealed trait implemented on field set markers. pub trait TypedDateDataMarkers: UnstableSealed { /// Marker for loading date skeleton patterns. type DateSkeletonPatternsV1Marker: DataMarker>; @@ -54,6 +58,8 @@ pub trait TypedDateDataMarkers: UnstableSealed { /// A trait associating types for date formatting in any calendar /// (data markers only). +/// +/// This is a sealed trait implemented on field set markers. pub trait DateDataMarkers: UnstableSealed { /// Cross-calendar data markers for date skeleta. type Skel: CalMarkers; @@ -67,6 +73,8 @@ pub trait DateDataMarkers: UnstableSealed { /// A trait associating types for time formatting /// (input types and data markers). +/// +/// This is a sealed trait implemented on field set markers. pub trait TimeMarkers: UnstableSealed { /// Marker for resolving the day-of-month input field. type HourInput: IntoOption; @@ -84,6 +92,8 @@ pub trait TimeMarkers: UnstableSealed { /// A trait associating types for time zone formatting /// (input types and data markers). +/// +/// This is a sealed trait implemented on field set markers. pub trait ZoneMarkers: UnstableSealed { /// Marker for resolving the time zone id input field. type TimeZoneIdInput: IntoOption; @@ -111,6 +121,8 @@ pub trait ZoneMarkers: UnstableSealed { /// A trait associating constants and types implementing various other traits /// required for datetime formatting. +/// +/// This is a sealed trait implemented on field set markers. pub trait DateTimeMarkers: UnstableSealed + DateTimeNamesMarker { /// Associated types for date formatting. /// @@ -128,7 +140,22 @@ pub trait DateTimeMarkers: UnstableSealed + DateTimeNamesMarker { type GluePatternV1Marker: DataMarker>; } -/// Trait to consolidate input markers. +/// Trait implemented on formattable datetime types. +/// +/// This trait allows for only those types compatible with a particular field set to be passed +/// as arguments to the formatting function for that field set. For example, this trait prevents +/// [`Time`] from being passed to a formatter parameterized with [`fieldsets::YMD`]. +/// +/// The following types implement this trait: +/// +/// - [`Date`](icu_calendar::Date) +/// - [`Time`](icu_calendar::Time) +/// - [`DateTime`](icu_calendar::DateTime) +/// - [`CustomZonedDateTime`](icu_timezone::CustomZonedDateTime) +/// - [`UtcOffset`](icu_timezone::UtcOffset) +/// - [`TimeZoneInfo`](icu_timezone::TimeZoneInfo) +/// +/// [`fieldsets::YMD`]: crate::fieldsets::YMD pub trait AllInputMarkers: GetField<::YearInput> + GetField<::MonthInput> @@ -174,6 +201,9 @@ where /// Trait to consolidate data provider markers defined by this crate /// for datetime formatting with a fixed calendar. +/// +/// This trait is implemented on all providers that support datetime formatting, +/// including [`crate::provider::Baked`]. pub trait AllFixedCalendarFormattingDataMarkers: DataProvider<>::YearNamesV1Marker> + DataProvider<>::MonthNamesV1Marker> @@ -223,6 +253,9 @@ where /// Trait to consolidate data provider markers defined by this crate /// for datetime formatting with any calendar. +/// +/// This trait is implemented on all providers that support datetime formatting, +/// including [`crate::provider::Baked`]. pub trait AllAnyCalendarFormattingDataMarkers: DataProvider<<::Year as CalMarkers>::Buddhist> + DataProvider<<::Year as CalMarkers>::Chinese> diff --git a/components/datetime/src/scaffold/get_field.rs b/components/datetime/src/scaffold/get_field.rs index 4dd047ed426..f1d382f3e8d 100644 --- a/components/datetime/src/scaffold/get_field.rs +++ b/components/datetime/src/scaffold/get_field.rs @@ -13,15 +13,19 @@ use icu_timezone::{ CustomZonedDateTime, TimeZoneBcp47Id, TimeZoneInfo, TimeZoneModel, UtcOffset, ZoneVariant, }; +use super::UnstableSealed; + /// A type that can return a certain field `T`. -pub trait GetField { +/// +/// This is used as a bound on various datetime functions. +pub trait GetField: UnstableSealed { /// Returns the value of this trait's field `T`. fn get_field(&self) -> T; } impl GetField for T where - T: Copy, + T: Copy + UnstableSealed, { #[inline] fn get_field(&self) -> T { @@ -29,6 +33,8 @@ where } } +impl> UnstableSealed for Date {} + impl> GetField for Date { #[inline] fn get_field(&self) -> YearInfo { @@ -64,6 +70,8 @@ impl> GetField for Date< } } +impl UnstableSealed for Time {} + impl GetField for Time { #[inline] fn get_field(&self) -> IsoHour { @@ -92,6 +100,8 @@ impl GetField for Time { } } +impl> UnstableSealed for DateTime {} + impl> GetField for DateTime { #[inline] fn get_field(&self) -> YearInfo { @@ -155,6 +165,8 @@ impl> GetField for DateTime } } +impl, Z> UnstableSealed for CustomZonedDateTime {} + impl, Z> GetField for CustomZonedDateTime { #[inline] fn get_field(&self) -> YearInfo { @@ -276,6 +288,8 @@ where } } +impl UnstableSealed for UtcOffset {} + impl GetField> for UtcOffset { #[inline] fn get_field(&self) -> Option { @@ -283,6 +297,8 @@ impl GetField> for UtcOffset { } } +impl UnstableSealed for TimeZoneInfo {} + impl GetField for TimeZoneInfo where O: TimeZoneModel,