use super::{reference, runtime, PatternItem};
use crate::{fields, options::preferences};
#[cfg(all(feature = "datagen"))]
use crate::{provider, skeleton};
use icu_provider::{yoke, zerofrom};
#[derive(Debug, PartialEq, Clone, Copy, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize, databake::Bake),
databake(path = icu_datetime::pattern),
)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[allow(clippy::exhaustive_enums)] pub enum CoarseHourCycle {
H11H12,
H23H24,
}
impl Default for CoarseHourCycle {
fn default() -> Self {
CoarseHourCycle::H23H24
}
}
impl CoarseHourCycle {
pub fn determine(pattern: &reference::Pattern) -> Option<Self> {
for item in pattern.items.iter() {
if let PatternItem::Field(fields::Field {
symbol: fields::FieldSymbol::Hour(pattern_hour),
length: _,
}) = item
{
return Some(match pattern_hour {
fields::Hour::H11 | fields::Hour::H12 => CoarseHourCycle::H11H12,
fields::Hour::H23 | fields::Hour::H24 => CoarseHourCycle::H23H24,
});
}
}
None
}
#[doc(hidden)]
#[cfg(all(feature = "datagen"))]
pub fn apply_on_pattern<'data>(
&self,
date_time: &provider::calendar::patterns::GenericLengthPatternsV1<'data>,
skeletons: &provider::calendar::DateSkeletonPatternsV1<'data>,
pattern_str: &str,
mut pattern: reference::Pattern,
) -> Option<reference::Pattern> {
for item in pattern.items_mut() {
if let PatternItem::Field(fields::Field { symbol, length: _ }) = item {
if let fields::FieldSymbol::Hour(pattern_hour) = symbol {
if match self {
CoarseHourCycle::H11H12 => match pattern_hour {
fields::Hour::H11 | fields::Hour::H12 => true,
fields::Hour::H23 | fields::Hour::H24 => false,
},
CoarseHourCycle::H23H24 => match pattern_hour {
fields::Hour::H11 | fields::Hour::H12 => false,
fields::Hour::H23 | fields::Hour::H24 => true,
},
} {
return Some(pattern_str.into());
} else {
*symbol = fields::FieldSymbol::Hour(match self {
CoarseHourCycle::H11H12 => fields::Hour::H12,
CoarseHourCycle::H23H24 => fields::Hour::H23,
});
break;
}
}
}
}
let skeleton = skeleton::reference::Skeleton::from(&pattern);
match skeleton::create_best_pattern_for_fields(
skeletons,
date_time,
skeleton.as_slice(),
&Default::default(),
true,
) {
skeleton::BestSkeleton::AllFieldsMatch(patterns)
| skeleton::BestSkeleton::MissingOrExtraFields(patterns) => {
Some(reference::Pattern::from(&patterns.expect_pattern(
"Only week-of patterns have plural variants",
)))
}
skeleton::BestSkeleton::NoMatch => None,
}
}
}
pub(crate) fn naively_apply_preferences(
pattern: &mut runtime::Pattern,
preferences: &Option<preferences::Bag>,
) {
if let Some(preferences::Bag {
hour_cycle: Some(hour_cycle),
}) = preferences
{
runtime::helpers::maybe_replace_first(pattern, |item| {
if let PatternItem::Field(fields::Field {
symbol: fields::FieldSymbol::Hour(current_hour),
length,
}) = item
{
if *current_hour != hour_cycle.field() {
Some(PatternItem::from((
fields::FieldSymbol::Hour(hour_cycle.field()),
*length,
)))
} else {
None
}
} else {
None
}
});
}
}