use jiff::{Unit, Zoned};
const SECONDS_PER_HOUR: usize = 60 * 60;
const SECONDS_PER_DAY: usize = SECONDS_PER_HOUR * 24;
const SECONDS_PER_YEAR: usize = SECONDS_PER_DAY * 365;
#[derive(Debug, Clone)]
pub struct ZonedExtent {
extent: Option<(Zoned, Zoned)>,
}
impl ZonedExtent {
pub fn new() -> Self {
Self { extent: None }
}
pub fn clear(&mut self) {
self.extent = None;
}
pub fn add(&mut self, value: &Zoned) {
match &mut self.extent {
None => self.extent = Some((value.clone(), value.clone())),
Some((min, max)) => {
if value < *min {
*min = value.clone();
}
if value > *max {
*max = value.clone();
}
}
}
}
pub fn earliest(&self) -> Option<Zoned> {
self.extent.as_ref().map(|(z, _)| z.clone())
}
pub fn lastest(&self) -> Option<Zoned> {
self.extent.as_ref().map(|(_, z)| z.clone())
}
pub fn count_seconds(&self) -> Option<usize> {
self.extent.as_ref().map(|(start, end)| {
let duration = start.duration_until(end);
let seconds = duration.as_secs();
seconds as usize
})
}
pub fn count_hours(&self) -> Option<usize> {
self.count_seconds()
.map(|seconds| (seconds as f64 / SECONDS_PER_HOUR as f64).ceil() as usize)
}
pub fn count_days(&self) -> Option<usize> {
self.count_seconds()
.map(|seconds| (seconds as f64 / SECONDS_PER_DAY as f64).ceil() as usize)
}
pub fn count_years(&self) -> Option<usize> {
self.count_seconds()
.map(|seconds| (seconds as f64 / SECONDS_PER_YEAR as f64).ceil() as usize)
}
pub fn count(&self, unit: Unit) -> Option<usize> {
match unit {
Unit::Second => self.count_seconds(),
Unit::Hour => self.count_hours(),
Unit::Day => self.count_days(),
Unit::Year => self.count_years(),
_ => unimplemented!(),
}
}
pub fn merge(&mut self, other: Self) {
match self.extent.as_mut() {
None => {
self.extent = other.extent;
}
Some((min, max)) => {
if let Some((other_min, other_max)) = other.extent {
if other_min < *min {
*min = other_min;
}
if other_max > *max {
*max = other_max;
}
}
}
}
}
}