#![no_std]
extern crate alloc;
use alloc::string::String;
use parser::ZoneInfoParseError;
use utils::epoch_seconds_for_year;
use hashbrown::HashMap;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "std")]
use std::{io, path::Path};
pub(crate) mod utils;
pub mod compiler;
pub mod parser;
pub mod posix;
pub mod rule;
pub mod types;
pub mod tzif;
pub mod zone;
#[doc(inline)]
pub use compiler::ZoneInfoCompiler;
#[doc(inline)]
pub use parser::ZoneInfoParser;
use rule::Rules;
use zone::ZoneRecord;
pub const ZONEINFO_FILES: [&str; 9] = [
"africa",
"antarctica",
"asia",
"australasia",
"backward",
"etcetera",
"europe",
"northamerica",
"southamerica",
];
#[derive(Debug)]
pub enum ZoneInfoError {
Parse(ZoneInfoParseError),
#[cfg(feature = "std")]
Io(io::Error),
}
#[cfg(feature = "std")]
impl From<io::Error> for ZoneInfoError {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Default)]
pub struct ZoneInfoData {
pub rules: HashMap<String, Rules>,
pub zones: HashMap<String, ZoneRecord>,
pub links: HashMap<String, String>,
pub pack_rat: HashMap<String, String>,
}
impl ZoneInfoData {
#[cfg(feature = "std")]
pub fn from_zoneinfo_directory<P: AsRef<Path>>(dir: P) -> Result<Self, ZoneInfoError> {
let mut zoneinfo = Self::default();
for filename in ZONEINFO_FILES {
let file_path = dir.as_ref().join(filename);
let parsed = Self::from_filepath(file_path)?;
zoneinfo.extend(parsed);
}
Ok(zoneinfo)
}
#[cfg(feature = "std")]
pub fn from_filepath<P: AsRef<Path> + core::fmt::Debug>(
path: P,
) -> Result<Self, ZoneInfoError> {
Self::from_zoneinfo_file(&std::fs::read_to_string(path)?)
}
pub fn from_zoneinfo_file(src: &str) -> Result<Self, ZoneInfoError> {
ZoneInfoParser::from_zoneinfo_str(src)
.parse()
.map_err(ZoneInfoError::Parse)
}
pub fn extend(&mut self, other: Self) {
self.rules.extend(other.rules);
self.zones.extend(other.zones);
self.links.extend(other.links);
self.pack_rat.extend(other.pack_rat);
}
}