mod adapter;
use crate::pattern::runtime::{self, PatternULE};
use alloc::borrow::Cow;
use icu_provider::prelude::*;
use zerovec::ule::{AsULE, UnvalidatedStr, ULE};
use zerovec::{VarZeroVec, ZeroMap};
#[cfg(feature = "experimental")]
use crate::neo_skeleton::NeoSkeletonLength;
#[cfg(feature = "experimental")]
use crate::pattern::runtime::PatternBorrowed;
#[cfg(feature = "experimental")]
use core::ops::Range;
#[allow(missing_docs)]
pub mod aux {
use crate::pattern::CoarseHourCycle;
use icu_locid::extensions::private::{subtag, Subtag};
pub const NUMERIC: Subtag = subtag!("1");
pub const ABBR: Subtag = subtag!("3");
pub const NARROW: Subtag = subtag!("4");
pub const WIDE: Subtag = subtag!("5");
pub const SHORT: Subtag = subtag!("6");
pub const ABBR_STANDALONE: Subtag = subtag!("3s");
pub const NARROW_STANDALONE: Subtag = subtag!("4s");
pub const WIDE_STANDALONE: Subtag = subtag!("5s");
pub const SHORT_STANDALONE: Subtag = subtag!("6s");
pub const PATTERN_FULL: Subtag = subtag!("f");
pub const PATTERN_LONG: Subtag = subtag!("l");
pub const PATTERN_MEDIUM: Subtag = subtag!("m");
pub const PATTERN_SHORT: Subtag = subtag!("s");
pub const PATTERN_FULL12: Subtag = subtag!("f12");
pub const PATTERN_LONG12: Subtag = subtag!("l12");
pub const PATTERN_MEDIUM12: Subtag = subtag!("m12");
pub const PATTERN_SHORT12: Subtag = subtag!("s12");
pub const PATTERN_FULL24: Subtag = subtag!("f24");
pub const PATTERN_LONG24: Subtag = subtag!("l24");
pub const PATTERN_MEDIUM24: Subtag = subtag!("m24");
pub const PATTERN_SHORT24: Subtag = subtag!("s24");
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[allow(clippy::exhaustive_enums)] pub enum Length {
Abbr,
Narrow,
Wide,
Short,
Numeric,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum PatternLength {
Full,
Long,
Medium,
Short,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[allow(clippy::exhaustive_enums)] pub enum Context {
Format,
Standalone,
}
pub fn symbol_subtag_info(subtag: Subtag) -> Option<(Context, Length)> {
use {Context::*, Length::*};
match subtag {
NUMERIC => Some((Format, Numeric)),
ABBR => Some((Format, Abbr)),
NARROW => Some((Format, Narrow)),
WIDE => Some((Format, Wide)),
SHORT => Some((Format, Short)),
ABBR_STANDALONE => Some((Standalone, Abbr)),
NARROW_STANDALONE => Some((Standalone, Narrow)),
WIDE_STANDALONE => Some((Standalone, Wide)),
SHORT_STANDALONE => Some((Standalone, Short)),
_ => None,
}
}
pub fn pattern_subtag_info(subtag: Subtag) -> Option<(PatternLength, Option<CoarseHourCycle>)> {
use {CoarseHourCycle::*, PatternLength::*};
match subtag {
PATTERN_FULL => Some((Full, None)),
PATTERN_LONG => Some((Long, None)),
PATTERN_MEDIUM => Some((Medium, None)),
PATTERN_SHORT => Some((Short, None)),
PATTERN_FULL12 => Some((Full, Some(H11H12))),
PATTERN_LONG12 => Some((Long, Some(H11H12))),
PATTERN_MEDIUM12 => Some((Medium, Some(H11H12))),
PATTERN_SHORT12 => Some((Short, Some(H11H12))),
PATTERN_FULL24 => Some((Full, Some(H23H24))),
PATTERN_LONG24 => Some((Long, Some(H23H24))),
PATTERN_MEDIUM24 => Some((Medium, Some(H23H24))),
PATTERN_SHORT24 => Some((Short, Some(H23H24))),
_ => None,
}
}
pub fn symbol_subtag_for(context: Context, length: Length) -> Subtag {
use {Context::*, Length::*};
match (context, length) {
(Format, Numeric) => NUMERIC,
(Format, Abbr) => ABBR,
(Format, Narrow) => NARROW,
(Format, Wide) => WIDE,
(Format, Short) => SHORT,
(Standalone, Numeric) => NUMERIC,
(Standalone, Abbr) => ABBR_STANDALONE,
(Standalone, Narrow) => NARROW_STANDALONE,
(Standalone, Wide) => WIDE_STANDALONE,
(Standalone, Short) => SHORT_STANDALONE,
}
}
pub fn pattern_subtag_for(
length: PatternLength,
hour_cycle: Option<CoarseHourCycle>,
) -> Subtag {
use {CoarseHourCycle::*, PatternLength::*};
match (length, hour_cycle) {
(Full, None) => PATTERN_FULL,
(Long, None) => PATTERN_LONG,
(Medium, None) => PATTERN_MEDIUM,
(Short, None) => PATTERN_SHORT,
(Full, Some(H11H12)) => PATTERN_FULL12,
(Long, Some(H11H12)) => PATTERN_LONG12,
(Medium, Some(H11H12)) => PATTERN_MEDIUM12,
(Short, Some(H11H12)) => PATTERN_SHORT12,
(Full, Some(H23H24)) => PATTERN_FULL24,
(Long, Some(H23H24)) => PATTERN_LONG24,
(Medium, Some(H23H24)) => PATTERN_MEDIUM24,
(Short, Some(H23H24)) => PATTERN_SHORT24,
}
}
}
size_test!(YearNamesV1, year_names_v1_size, 48);
#[doc = year_names_v1_size!()]
#[icu_provider::data_struct(
marker(BuddhistYearNamesV1Marker, "datetime/symbols/buddhist/years@1"),
marker(ChineseYearNamesV1Marker, "datetime/symbols/chinese/years@1"),
marker(CopticYearNamesV1Marker, "datetime/symbols/coptic/years@1"),
marker(DangiYearNamesV1Marker, "datetime/symbols/dangi/years@1"),
marker(EthiopianYearNamesV1Marker, "datetime/symbols/ethiopic/years@1"),
marker(GregorianYearNamesV1Marker, "datetime/symbols/gregory/years@1"),
marker(HebrewYearNamesV1Marker, "datetime/symbols/hebrew/years@1"),
marker(IndianYearNamesV1Marker, "datetime/symbols/indian/years@1"),
marker(IslamicYearNamesV1Marker, "datetime/symbols/islamic/years@1"),
marker(JapaneseYearNamesV1Marker, "datetime/symbols/japanese/years@1"),
marker(JapaneseExtendedYearNamesV1Marker, "datetime/symbols/japanext/years@1"),
marker(PersianYearNamesV1Marker, "datetime/symbols/persian/years@1"),
marker(RocYearNamesV1Marker, "datetime/symbols/roc/years@1")
)]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub enum YearNamesV1<'data> {
Eras(#[cfg_attr(feature = "serde", serde(borrow))] ZeroMap<'data, UnvalidatedStr, str>),
Cyclic(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
}
size_test!(MonthNamesV1, month_names_v1_size, 32);
#[doc = month_names_v1_size!()]
#[icu_provider::data_struct(
marker(BuddhistMonthNamesV1Marker, "datetime/symbols/buddhist/months@1"),
marker(ChineseMonthNamesV1Marker, "datetime/symbols/chinese/months@1"),
marker(CopticMonthNamesV1Marker, "datetime/symbols/coptic/months@1"),
marker(DangiMonthNamesV1Marker, "datetime/symbols/dangi/months@1"),
marker(EthiopianMonthNamesV1Marker, "datetime/symbols/ethiopic/months@1"),
marker(GregorianMonthNamesV1Marker, "datetime/symbols/gregory/months@1"),
marker(HebrewMonthNamesV1Marker, "datetime/symbols/hebrew/months@1"),
marker(IndianMonthNamesV1Marker, "datetime/symbols/indian/months@1"),
marker(IslamicMonthNamesV1Marker, "datetime/symbols/islamic/months@1"),
marker(JapaneseMonthNamesV1Marker, "datetime/symbols/japanese/months@1"),
marker(
JapaneseExtendedMonthNamesV1Marker,
"datetime/symbols/japanext/months@1"
),
marker(PersianMonthNamesV1Marker, "datetime/symbols/persian/months@1"),
marker(RocMonthNamesV1Marker, "datetime/symbols/roc/months@1")
)]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub enum MonthNamesV1<'data> {
Linear(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
LeapLinear(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
LeapNumeric(#[cfg_attr(feature = "serde", serde(borrow))] SimpleSubstitutionPattern<'data>),
}
#[derive(Debug, PartialEq, Clone, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct SimpleSubstitutionPattern<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub pattern: Cow<'data, str>,
pub subst_index: usize,
}
impl SimpleSubstitutionPattern<'_> {
#[cfg(feature = "experimental")]
pub(crate) fn get_prefix(&self) -> &str {
self.debug_unwrap_range(0..self.subst_index)
}
#[cfg(feature = "experimental")]
pub(crate) fn get_suffix(&self) -> &str {
self.debug_unwrap_range(self.subst_index..self.pattern.len())
}
#[cfg(feature = "experimental")]
fn debug_unwrap_range(&self, range: Range<usize>) -> &str {
match self.pattern.get(range) {
Some(s) => s,
None => {
debug_assert!(false, "Invalid pattern: {self:?}");
""
}
}
}
}
size_test!(LinearNamesV1, linear_names_v1_size, 24);
#[doc = linear_names_v1_size!()]
#[icu_provider::data_struct(
marker(WeekdayNamesV1Marker, "datetime/symbols/weekdays@1"),
marker(DayPeriodNamesV1Marker, "datetime/symbols/dayperiods@1"),
marker(ChineseDaySymbolsV1Marker, "datetime/symbols/chinese/days@1"),
marker(DangiDaySymbolsV1Marker, "datetime/symbols/dangi/days@1"),
marker(PlaceholderDaySymbolsV1Marker, "datetime/symbols/placeholder/days@1"),
)]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub struct LinearNamesV1<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub symbols: VarZeroVec<'data, str>,
}
impl<'data> LinearNamesV1<'data> {
#[cfg(feature = "experimental")]
pub(crate) fn am(&self) -> Option<&str> {
self.symbols.get(0)
}
#[cfg(feature = "experimental")]
pub(crate) fn pm(&self) -> Option<&str> {
self.symbols.get(1)
}
#[cfg(feature = "experimental")]
pub(crate) fn noon(&self) -> Option<&str> {
self.symbols
.get(2)
.and_then(|s| if s.is_empty() { None } else { Some(s) })
}
#[cfg(feature = "experimental")]
pub(crate) fn midnight(&self) -> Option<&str> {
self.symbols.get(3)
}
}
size_test!(DatePatternV1, date_pattern_v1_size, 32);
#[doc = date_pattern_v1_size!()]
#[icu_provider::data_struct(
marker(BuddhistDatePatternV1Marker, "datetime/patterns/buddhist/date@1"),
marker(ChineseDatePatternV1Marker, "datetime/patterns/chinese/date@1"),
marker(CopticDatePatternV1Marker, "datetime/patterns/coptic/date@1"),
marker(DangiDatePatternV1Marker, "datetime/patterns/dangi/date@1"),
marker(EthiopianDatePatternV1Marker, "datetime/patterns/ethiopic/date@1"),
marker(GregorianDatePatternV1Marker, "datetime/patterns/gregory/date@1"),
marker(HebrewDatePatternV1Marker, "datetime/patterns/hebrew/date@1"),
marker(IndianDatePatternV1Marker, "datetime/patterns/indian/date@1"),
marker(IslamicDatePatternV1Marker, "datetime/patterns/islamic/date@1"),
marker(JapaneseDatePatternV1Marker, "datetime/patterns/japanese/date@1"),
marker(JapaneseExtendedDatePatternV1Marker, "datetime/patterns/japanext/date@1"),
marker(PersianDatePatternV1Marker, "datetime/patterns/persian/date@1"),
marker(RocDatePatternV1Marker, "datetime/patterns/roc/date@1")
)]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub struct DatePatternV1<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub pattern: runtime::Pattern<'data>,
}
size_test!(TimePatternV1, time_pattern_v1_size, 32);
#[doc = time_pattern_v1_size!()]
#[icu_provider::data_struct(marker(TimePatternV1Marker, "datetime/patterns/time@1"))]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub struct TimePatternV1<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub pattern: runtime::Pattern<'data>,
}
size_test!(DateTimePatternV1, date_time_pattern_v1_size, 24);
#[doc = date_time_pattern_v1_size!()]
#[icu_provider::data_struct(marker(DateTimePatternV1Marker, "datetime/patterns/datetime@1"))]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub struct DateTimePatternV1<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub pattern: runtime::GenericPattern<'data>,
}
#[allow(missing_docs)] #[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct SkeletonDataIndex {
pub has_long: bool,
pub has_medium: bool,
pub has_plurals: bool,
}
impl SkeletonDataIndex {
#[cfg(feature = "experimental")]
pub(crate) fn index_for(self, length: NeoSkeletonLength) -> u8 {
match (length, self.has_long, self.has_medium) {
(NeoSkeletonLength::Long, _, _) => 0,
(NeoSkeletonLength::Medium, true, _) => 1,
(NeoSkeletonLength::Medium, false, _) => 0,
(NeoSkeletonLength::Short, true, true) => 2,
(NeoSkeletonLength::Short, true, false) => 1,
(NeoSkeletonLength::Short, false, true) => 1,
(NeoSkeletonLength::Short, false, false) => 0,
}
}
}
#[derive(Debug, Copy, Clone, ULE)]
#[repr(transparent)]
pub struct SkeletonDataIndexULE(u8);
impl AsULE for SkeletonDataIndex {
type ULE = SkeletonDataIndexULE;
fn to_unaligned(self) -> Self::ULE {
let mut flags = 0;
flags |= (self.has_long as u8) << 7;
flags |= (self.has_medium as u8) << 6;
flags |= (self.has_plurals as u8) << 5;
SkeletonDataIndexULE(flags)
}
fn from_unaligned(unaligned: Self::ULE) -> Self {
let flags = unaligned.0;
SkeletonDataIndex {
has_long: (flags & (1 << 7)) != 0,
has_medium: (flags & (1 << 6)) != 0,
has_plurals: (flags & (1 << 5)) != 0,
}
}
}
#[icu_provider::data_struct(
marker(BuddhistDateNeoSkeletonPatternsV1Marker, "datetime/patterns/buddhist/skeleton@1"),
marker(ChineseDateNeoSkeletonPatternsV1Marker, "datetime/patterns/chinese/skeleton@1"),
marker(CopticDateNeoSkeletonPatternsV1Marker, "datetime/patterns/coptic/skeleton@1"),
marker(DangiDateNeoSkeletonPatternsV1Marker, "datetime/patterns/dangi/skeleton@1"),
marker(EthiopianDateNeoSkeletonPatternsV1Marker, "datetime/patterns/ethiopic/skeleton@1"),
marker(GregorianDateNeoSkeletonPatternsV1Marker, "datetime/patterns/gregory/skeleton@1"),
marker(HebrewDateNeoSkeletonPatternsV1Marker, "datetime/patterns/hebrew/skeleton@1"),
marker(IndianDateNeoSkeletonPatternsV1Marker, "datetime/patterns/indian/skeleton@1"),
marker(IslamicDateNeoSkeletonPatternsV1Marker, "datetime/patterns/islamic/skeleton@1"),
marker(JapaneseDateNeoSkeletonPatternsV1Marker, "datetime/patterns/japanese/skeleton@1"),
marker(JapaneseExtendedDateNeoSkeletonPatternsV1Marker, "datetime/patterns/japanext/skeleton@1"),
marker(PersianDateNeoSkeletonPatternsV1Marker, "datetime/patterns/persian/skeleton@1"),
marker(RocDateNeoSkeletonPatternsV1Marker, "datetime/patterns/roc/skeleton@1"),
marker(TimeNeoSkeletonPatternsV1Marker, "datetime/patterns/time_skeleton@1")
)]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[allow(missing_docs)] pub struct PackedSkeletonDataV1<'data> {
#[allow(missing_docs)] pub index_info: SkeletonDataIndex,
#[allow(missing_docs)] #[cfg_attr(feature = "serde", serde(borrow))]
pub patterns: VarZeroVec<'data, PatternULE>,
}
impl<'data> PackedSkeletonDataV1<'data> {
#[cfg(feature = "experimental")]
pub(crate) fn get_pattern(&self, length: NeoSkeletonLength) -> PatternBorrowed {
match self
.patterns
.get(self.index_info.index_for(length) as usize)
{
Some(pattern_ule) => pattern_ule.as_borrowed(),
None => {
debug_assert!(false, "failed to load a pattern for length {length:?}");
PatternBorrowed::DEFAULT
}
}
}
}
#[icu_provider::data_struct(marker(
DateTimeSkeletonPatternsV1Marker,
"datetime/patterns/datetime_skeleton@1"
))]
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::provider::neo),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
#[allow(missing_docs)] pub struct DateTimeSkeletonsV1<'data> {
#[allow(missing_docs)] #[cfg_attr(feature = "serde", serde(borrow))]
pub map: ZeroMap<'data, str, PatternULE>,
}
#[derive(Debug)]
pub struct YearNamesV1Marker;
impl DataMarker for YearNamesV1Marker {
type Yokeable = YearNamesV1<'static>;
}
#[derive(Debug)]
pub struct MonthNamesV1Marker;
impl DataMarker for MonthNamesV1Marker {
type Yokeable = MonthNamesV1<'static>;
}
#[derive(Debug)]
pub struct DatePatternV1Marker;
impl DataMarker for DatePatternV1Marker {
type Yokeable = DatePatternV1<'static>;
}
#[derive(Debug)]
pub struct SkeletaV1Marker;
impl DataMarker for SkeletaV1Marker {
type Yokeable = PackedSkeletonDataV1<'static>;
}