use crate::size_test_macro::size_test;
use alloc::borrow::Cow;
use icu_pattern::SinglePlaceholderPattern;
use icu_provider::prelude::*;
#[cfg(feature = "serde")]
use potential_utf::PotentialUtf8;
use zerovec::VarZeroVec;
#[cfg(feature = "serde")]
use zerovec::{ule::tuplevar::Tuple2VarULE, VarZeroCow, VarZeroSlice};
icu_provider::data_marker!(
DatetimeNamesYearBuddhistV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearChineseV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearCopticV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearDangiV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearEthiopianV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearGregorianV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearHebrewV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearIndianV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearHijriV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearJapaneseV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearPersianV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesYearRocV1,
YearNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_year_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthBuddhistV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthChineseV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthCopticV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthDangiV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthEthiopianV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthGregorianV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthHebrewV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthIndianV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthHijriV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthJapaneseV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthPersianV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesMonthRocV1,
MonthNames<'static>,
#[cfg(feature = "datagen")]
attributes_domain = "datetime_month_length"
);
icu_provider::data_marker!(
DatetimeNamesWeekdayV1,
LinearNames<'static>,
);
icu_provider::data_marker!(
DatetimeNamesDayperiodV1,
LinearNames<'static>,
);
icu_provider::data_marker!(
DatetimeNamesDayChineseV1,
LinearNames<'static>,
);
icu_provider::data_marker!(
DatetimeNamesDayDangiV1,
LinearNames<'static>,
);
icu_provider::data_marker!(
DatetimeNamesDayPlaceholderV1,
LinearNames<'static>,
);
size_test!(YearNames, year_names_v1_size, 32);
#[doc = year_names_v1_size!()]
#[derive(Debug, PartialEq, Clone, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(feature = "datagen", derive(databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_datetime::provider::names))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub enum YearNames<'data> {
FixedEras(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
#[cfg(feature = "serde")]
VariableEras(#[cfg_attr(feature = "serde", serde(borrow))] YearNamesMap<'data>),
Cyclic(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
}
#[cfg(feature = "serde")]
impl serde::Serialize for YearNames<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use alloc::vec::Vec;
#[derive(serde::Serialize)]
enum Raw<'a> {
FixedEras(&'a VarZeroVec<'a, str>),
VariableEras(&'a YearNamesMap<'a>),
Cyclic(&'a VarZeroVec<'a, str>),
}
let x: YearNamesMap;
match self {
Self::FixedEras(e) if e.len() == 7 => {
let mut kvs = [
PotentialUtf8::from_str("bce"),
PotentialUtf8::from_str("ce"),
PotentialUtf8::from_str("meiji"),
PotentialUtf8::from_str("taisho"),
PotentialUtf8::from_str("showa"),
PotentialUtf8::from_str("heisei"),
PotentialUtf8::from_str("reiwa"),
]
.into_iter()
.zip(e.iter())
.collect::<Vec<_>>();
kvs.sort_unstable();
let (ks, vs) = kvs.into_iter().unzip::<_, _, Vec<_>, Vec<_>>();
x = VarZeroCow::from_encodeable(&(ks, vs));
Raw::VariableEras(&x)
}
Self::FixedEras(e) => Raw::FixedEras(e),
Self::VariableEras(e) => Raw::VariableEras(e),
Self::Cyclic(c) => Raw::Cyclic(c),
}
.serialize(serializer)
}
}
icu_provider::data_struct!(
YearNames<'_>,
#[cfg(feature = "datagen")]
);
#[cfg(feature = "serde")]
type YearNamesMap<'data> =
VarZeroCow<'data, Tuple2VarULE<VarZeroSlice<PotentialUtf8>, VarZeroSlice<str>>>;
#[cfg(feature = "serde")]
pub(crate) fn get_year_name_from_map<'a>(
map: &'a YearNamesMap<'_>,
year: &PotentialUtf8,
) -> Option<&'a str> {
let idx = map.a().binary_search_by(|x| x.cmp(year)).ok()?;
map.b().get(idx)
}
size_test!(MonthNames, month_names_v1_size, 32);
#[doc = month_names_v1_size!()]
#[derive(Debug, PartialEq, Clone, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(feature = "datagen", derive(databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_datetime::provider::names))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub enum MonthNames<'data> {
Linear(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
#[cfg(feature = "serde")]
LeapLinear(#[cfg_attr(feature = "serde", serde(borrow))] VarZeroVec<'data, str>),
LeapNumeric(
#[cfg_attr(
feature = "serde",
serde(
borrow,
deserialize_with = "icu_pattern::deserialize_borrowed_cow::<icu_pattern::SinglePlaceholder, _>"
)
)]
Cow<'data, SinglePlaceholderPattern>,
),
LeapPattern(VarZeroVec<'data, str>),
}
#[cfg(feature = "serde")]
impl serde::Serialize for MonthNames<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(serde::Serialize)]
enum Raw<'a> {
Linear(&'a VarZeroVec<'a, str>),
LeapLinear(&'a VarZeroVec<'a, str>),
LeapNumeric(&'a Cow<'a, SinglePlaceholderPattern>),
}
let z;
match self {
Self::Linear(l) => Raw::Linear(l),
Self::LeapLinear(l) => Raw::LeapLinear(l),
Self::LeapNumeric(l) => Raw::LeapNumeric(l),
Self::LeapPattern(l) => {
use alloc::string::String;
use alloc::vec::Vec;
use zerovec::vecs::VarZeroVecOwned;
let leap_pattern = l.get(l.len() - 2).unwrap_or_default();
let leap_base_pattern = l.get(l.len() - 1).unwrap_or_default();
let normal_names = l.iter().take(l.len() - 2);
let r = if leap_pattern.starts_with('\0') {
normal_names
.map(String::from)
.chain([
String::new(),
String::new(),
String::new(),
String::new(),
SinglePlaceholderPattern::from_ref_store(leap_pattern)
.unwrap_or(SinglePlaceholderPattern::PASS_THROUGH)
.interpolate_to_string([l.get(5).unwrap_or_default()]),
SinglePlaceholderPattern::from_ref_store(leap_base_pattern)
.unwrap_or(SinglePlaceholderPattern::PASS_THROUGH)
.interpolate_to_string([l.get(5).unwrap_or_default()]),
String::new(),
String::new(),
String::new(),
String::new(),
String::new(),
String::new(),
])
.collect()
} else {
normal_names
.clone()
.map(String::from)
.chain(normal_names.map(|m| {
SinglePlaceholderPattern::from_ref_store(leap_pattern)
.unwrap_or(SinglePlaceholderPattern::PASS_THROUGH)
.interpolate_to_string([m])
}))
.collect::<Vec<_>>()
};
#[allow(clippy::unwrap_used)] {
z = VarZeroVecOwned::try_from_elements(&r).unwrap().into();
}
Raw::LeapLinear(&z)
}
}
.serialize(serializer)
}
}
icu_provider::data_struct!(
MonthNames<'_>,
#[cfg(feature = "datagen")]
);
size_test!(LinearNames, linear_names_v1_size, 24);
#[doc = linear_names_v1_size!()]
#[derive(Debug, PartialEq, Clone, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_datetime::provider::names))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[yoke(prove_covariance_manually)]
pub struct LinearNames<'data> {
#[cfg_attr(feature = "serde", serde(borrow))]
pub names: VarZeroVec<'data, str>,
}
icu_provider::data_struct!(
LinearNames<'_>,
#[cfg(feature = "datagen")]
);
impl LinearNames<'_> {
pub(crate) fn am(&self) -> Option<&str> {
self.names.get(0)
}
pub(crate) fn pm(&self) -> Option<&str> {
self.names.get(1)
}
pub(crate) fn noon(&self) -> Option<&str> {
self.names
.get(2)
.and_then(|s| if s.is_empty() { None } else { Some(s) })
}
pub(crate) fn midnight(&self) -> Option<&str> {
self.names.get(3)
}
}
#[derive(Debug)]
pub struct YearNamesV1;
impl DynamicDataMarker for YearNamesV1 {
type DataStruct = YearNames<'static>;
}
#[derive(Debug)]
pub struct MonthNamesV1;
impl DynamicDataMarker for MonthNamesV1 {
type DataStruct = MonthNames<'static>;
}
pub use DatetimeNamesWeekdayV1 as WeekdayNamesV1;
pub use DatetimeNamesDayperiodV1 as DayPeriodNamesV1;