use alloc::boxed::Box;
use alloc::sync::Arc;
use crate::Offset;
use crate::offset::OffsetName;
#[cfg(feature = "std")]
mod tzif;
pub(crate) struct Location {
transitions: Box<[Transition]>,
zones: Box<[Zone]>,
}
struct Transition {
when: i64,
zone: u8,
}
#[derive(Debug)]
struct Zone {
offset: i32,
dst: bool,
name: Arc<str>,
}
impl Location {
#[cfg(feature = "std")]
pub(crate) fn of(id: &str) -> crate::Result<Self> {
let location = tzif::read(std::path::Path::new("/usr/share/zoneinfo").join(id))?;
Ok(location)
}
#[allow(unused_variables)]
#[cfg(not(feature = "std"))]
pub(crate) fn of(id: &str) -> crate::Result<Self> {
Err(crate::error::ErrorKind::TimeZoneFile.into())
}
pub(crate) fn offset_at_utc_seconds(&self, seconds: i64) -> Offset {
match self.transitions.binary_search_by(|t| t.when.cmp(&seconds)) {
Ok(index) => self.offset_at_transition_index(index),
Err(index) if index == 0 => {
todo!()
}
Err(index) if index == self.transitions.len() => {
todo!()
}
Err(index) => self.offset_at_transition_index(index - 1),
}
}
fn offset_at_transition_index(&self, index: usize) -> Offset {
let zone = self.transitions[index].zone;
let zone = &self.zones[zone as usize];
Offset {
name: OffsetName::Location(zone.name.clone()),
seconds: zone.offset,
dst: Some(zone.dst),
}
}
}