Skip to content

Commit

Permalink
Make GetField sealed; other datetime docs fixes (#5858)
Browse files Browse the repository at this point in the history
Fixes #5633
  • Loading branch information
sffc authored Nov 23, 2024
1 parent cf219d4 commit 5cd4091
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 6 deletions.
26 changes: 25 additions & 1 deletion components/datetime/src/fieldsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1182,6 +1204,8 @@ impl_time_marker!(
/// "24:00"
/// );
/// ```
///
/// [`DateTimeFormatterPreferences`]: crate::DateTimeFormatterPreferences
T,
description = "time (locale-dependent hour cycle)",
sample_length = medium,
Expand Down
23 changes: 22 additions & 1 deletion components/datetime/src/neo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,28 @@ use icu_provider::prelude::*;
use writeable::{impl_display_with_writeable, Writeable};

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,
{
Expand Down
2 changes: 1 addition & 1 deletion components/datetime/src/scaffold/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions components/datetime/src/scaffold/dynamic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
35 changes: 34 additions & 1 deletion components/datetime/src/scaffold/fieldset_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<YearInfo>;
Expand All @@ -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<C>: UnstableSealed {
/// Marker for loading date skeleton patterns.
type DateSkeletonPatternsV1Marker: DataMarker<DataStruct = PackedPatternsV1<'static>>;
Expand All @@ -54,6 +58,8 @@ pub trait TypedDateDataMarkers<C>: 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<ErasedPackedPatterns>;
Expand All @@ -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<IsoHour>;
Expand All @@ -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<TimeZoneBcp47Id>;
Expand Down Expand Up @@ -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.
///
Expand All @@ -128,7 +140,22 @@ pub trait DateTimeMarkers: UnstableSealed + DateTimeNamesMarker {
type GluePatternV1Marker: DataMarker<DataStruct = GluePatternV1<'static>>;
}

/// 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<R: DateTimeMarkers>:
GetField<<R::D as DateInputMarkers>::YearInput>
+ GetField<<R::D as DateInputMarkers>::MonthInput>
Expand Down Expand Up @@ -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<C: CldrCalendar, FSet: DateTimeMarkers>:
DataProvider<<FSet::D as TypedDateDataMarkers<C>>::YearNamesV1Marker>
+ DataProvider<<FSet::D as TypedDateDataMarkers<C>>::MonthNamesV1Marker>
Expand Down Expand Up @@ -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<FSet: DateTimeMarkers>:
DataProvider<<<FSet::D as DateDataMarkers>::Year as CalMarkers<YearNamesV1Marker>>::Buddhist>
+ DataProvider<<<FSet::D as DateDataMarkers>::Year as CalMarkers<YearNamesV1Marker>>::Chinese>
Expand Down
20 changes: 18 additions & 2 deletions components/datetime/src/scaffold/get_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,28 @@ use icu_timezone::{
CustomZonedDateTime, TimeZoneBcp47Id, TimeZoneInfo, TimeZoneModel, UtcOffset, ZoneVariant,
};

use super::UnstableSealed;

/// A type that can return a certain field `T`.
pub trait GetField<T> {
///
/// This is used as a bound on various datetime functions.
pub trait GetField<T>: UnstableSealed {
/// Returns the value of this trait's field `T`.
fn get_field(&self) -> T;
}

impl<T> GetField<T> for T
where
T: Copy,
T: Copy + UnstableSealed,
{
#[inline]
fn get_field(&self) -> T {
*self
}
}

impl<C: Calendar, A: AsCalendar<Calendar = C>> UnstableSealed for Date<A> {}

impl<C: Calendar, A: AsCalendar<Calendar = C>> GetField<YearInfo> for Date<A> {
#[inline]
fn get_field(&self) -> YearInfo {
Expand Down Expand Up @@ -64,6 +70,8 @@ impl<C: Calendar, A: AsCalendar<Calendar = C>> GetField<DayOfYearInfo> for Date<
}
}

impl UnstableSealed for Time {}

impl GetField<IsoHour> for Time {
#[inline]
fn get_field(&self) -> IsoHour {
Expand Down Expand Up @@ -92,6 +100,8 @@ impl GetField<NanoSecond> for Time {
}
}

impl<C: Calendar, A: AsCalendar<Calendar = C>> UnstableSealed for DateTime<A> {}

impl<C: Calendar, A: AsCalendar<Calendar = C>> GetField<YearInfo> for DateTime<A> {
#[inline]
fn get_field(&self) -> YearInfo {
Expand Down Expand Up @@ -155,6 +165,8 @@ impl<C: Calendar, A: AsCalendar<Calendar = C>> GetField<NanoSecond> for DateTime
}
}

impl<C: Calendar, A: AsCalendar<Calendar = C>, Z> UnstableSealed for CustomZonedDateTime<A, Z> {}

impl<C: Calendar, A: AsCalendar<Calendar = C>, Z> GetField<YearInfo> for CustomZonedDateTime<A, Z> {
#[inline]
fn get_field(&self) -> YearInfo {
Expand Down Expand Up @@ -276,13 +288,17 @@ where
}
}

impl UnstableSealed for UtcOffset {}

impl GetField<Option<UtcOffset>> for UtcOffset {
#[inline]
fn get_field(&self) -> Option<UtcOffset> {
Some(*self)
}
}

impl<O: TimeZoneModel> UnstableSealed for TimeZoneInfo<O> {}

impl<O> GetField<TimeZoneBcp47Id> for TimeZoneInfo<O>
where
O: TimeZoneModel,
Expand Down

0 comments on commit 5cd4091

Please sign in to comment.