diff --git a/components/datetime/src/pattern/mod.rs b/components/datetime/src/pattern/mod.rs index 529eb7e956e..3053b21deff 100644 --- a/components/datetime/src/pattern/mod.rs +++ b/components/datetime/src/pattern/mod.rs @@ -7,7 +7,7 @@ mod error; pub mod hour_cycle; mod item; #[cfg(feature = "experimental")] -mod neo; +pub mod neo; pub mod reference; pub mod runtime; diff --git a/components/datetime/src/pattern/neo.rs b/components/datetime/src/pattern/neo.rs index 7423f109bb6..4705d7074e1 100644 --- a/components/datetime/src/pattern/neo.rs +++ b/components/datetime/src/pattern/neo.rs @@ -2,14 +2,17 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use core::{marker::PhantomData, str::FromStr}; +use core::marker::PhantomData; +use core::str::FromStr; use super::{runtime, PatternError}; use crate::options::length; +use crate::provider::neo::*; +use crate::CldrCalendar; use crate::Error; -use crate::{provider::neo::*, CldrCalendar}; use icu_provider::prelude::*; +#[derive(Debug)] enum DateTimePatternInner { Custom(runtime::Pattern<'static>), Date(DataPayload), @@ -21,6 +24,7 @@ enum DateTimePatternInner { }, } +#[derive(Debug)] pub struct TypedDateTimePattern { inner: DateTimePatternInner, _calendar: PhantomData, @@ -35,6 +39,55 @@ impl TypedDateTimePattern { }) } + /// Loads a [`TypedDateTimePattern`] for a date length. + /// + /// # Examples + /// + /// ``` + /// use icu::calendar::Gregorian; + /// use icu::datetime::pattern::neo::TypedDateTimePattern; + /// use icu::datetime::options::length; + /// use icu::locid::locale; + /// + /// let expected_pattern = TypedDateTimePattern::::try_from_pattern_str("d MMM y").unwrap(); + /// let actual_pattern = TypedDateTimePattern::::try_new_date_with_length_unstable( + /// &icu::datetime::provider::Baked, + /// &locale!("fr").into(), + /// length::Date::Medium, + /// ).unwrap(); + /// + /// assert_eq!(expected_pattern, actual_pattern); + /// ``` + pub fn try_new_date_with_length_unstable

( + provider: &P, + locale: &DataLocale, + length: length::Date, + ) -> Result + where + P: DataProvider + ?Sized, + { + let mut locale = locale.clone(); + locale.set_aux(AuxiliaryKeys::from_subtag(aux::pattern_subtag_for( + match length { + length::Date::Full => aux::PatternLength::Full, + length::Date::Long => aux::PatternLength::Long, + length::Date::Medium => aux::PatternLength::Medium, + length::Date::Short => aux::PatternLength::Short, + }, + None, // no hour cycle for date patterns + ))); + let payload = provider + .load(DataRequest { + locale: &locale, + metadata: Default::default(), + })? + .take_payload()?; + Ok(Self { + inner: DateTimePatternInner::Date(payload.cast()), + _calendar: PhantomData, + }) + } + pub(crate) fn as_borrowed(&self) -> DateTimePatternBorrowed { let borrowed_inner = match self.inner { DateTimePatternInner::Custom(ref pattern) => { @@ -69,7 +122,17 @@ impl FromStr for TypedDateTimePattern { } } -#[derive(Debug, Copy, Clone)] +// Check equality on the borrowed variant since it flattens the difference +// between the three `Single`` pattern variants, which is not public-facing +impl PartialEq for TypedDateTimePattern { + fn eq(&self, other: &Self) -> bool { + self.as_borrowed().eq(&other.as_borrowed()) + } +} + +impl Eq for TypedDateTimePattern {} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] enum DateTimePatternBorrowedInner<'a> { Single(&'a runtime::Pattern<'a>), DateTime { @@ -80,7 +143,7 @@ enum DateTimePatternBorrowedInner<'a> { } // Not clear if this needs to be public. For now, make it private. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub(crate) struct DateTimePatternBorrowed<'a> { inner: DateTimePatternBorrowedInner<'a>, }