use crate::provider::{MetazoneId, TimeZoneBcp47Id};
use crate::error::TimeZoneError;
use crate::provider::MetazonePeriodV1Marker;
use icu_calendar::DateTime;
use icu_calendar::Iso;
use icu_provider::prelude::*;
use zerovec::ule::AsULE;
#[derive(Debug)]
pub struct MetazoneCalculator {
pub(super) metazone_period: DataPayload<MetazonePeriodV1Marker>,
}
#[cfg(feature = "compiled_data")]
impl Default for MetazoneCalculator {
fn default() -> Self {
Self::new()
}
}
impl MetazoneCalculator {
#[cfg(feature = "compiled_data")]
#[inline]
pub const fn new() -> Self {
MetazoneCalculator {
metazone_period: DataPayload::from_static_ref(
crate::provider::Baked::SINGLETON_TIME_ZONE_METAZONE_PERIOD_V1,
),
}
}
icu_provider::gen_any_buffer_data_constructors!(locale: skip, options: skip, error: TimeZoneError,
#[cfg(skip)]
functions: [
new,
try_new_with_any_provider,
try_new_with_buffer_provider,
try_new_unstable,
Self,
]
);
#[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new)]
pub fn try_new_unstable(
provider: &(impl DataProvider<MetazonePeriodV1Marker> + ?Sized),
) -> Result<Self, TimeZoneError> {
let metazone_period = provider.load(Default::default())?.take_payload()?;
Ok(Self { metazone_period })
}
pub fn compute_metazone_from_time_zone(
&self,
time_zone_id: TimeZoneBcp47Id,
local_datetime: &DateTime<Iso>,
) -> Option<MetazoneId> {
match self.metazone_period.get().0.get0(&time_zone_id) {
Some(cursor) => {
let mut metazone_id = None;
let minutes_since_local_unix_epoch =
local_datetime.minutes_since_local_unix_epoch();
for (minutes, id) in cursor.iter1() {
if minutes_since_local_unix_epoch >= i32::from_unaligned(*minutes) {
metazone_id = id.get()
} else {
break;
}
}
metazone_id
}
None => None,
}
}
}