use jiff::{SignedDuration, Zoned};
use crate::ordinal::Ordinal;
use crate::time_unit::{DaysOfMonth, Hours, Minutes, Months, Seconds, TimeUnitField};
const ONE_SECOND: SignedDuration = SignedDuration::from_secs(1);
pub struct NextAfterQuery {
initial_datetime: Zoned,
first_month: bool,
first_day_of_month: bool,
first_hour: bool,
first_minute: bool,
first_second: bool,
}
impl NextAfterQuery {
pub fn from(after: &Zoned) -> NextAfterQuery {
NextAfterQuery {
initial_datetime: after.clone().saturating_add(ONE_SECOND),
first_month: true,
first_day_of_month: true,
first_hour: true,
first_minute: true,
first_second: true,
}
}
pub fn year_lower_bound(&self) -> Ordinal {
self.initial_datetime.year() as u32
}
pub fn month_lower_bound(&mut self) -> Ordinal {
if self.first_month {
self.first_month = false;
return self.initial_datetime.month() as u32;
}
Months::inclusive_min()
}
pub fn reset_month(&mut self) {
self.first_month = false;
self.reset_day_of_month();
}
pub fn day_of_month_lower_bound(&mut self) -> Ordinal {
if self.first_day_of_month {
self.first_day_of_month = false;
return self.initial_datetime.day() as u32;
}
DaysOfMonth::inclusive_min()
}
pub fn reset_day_of_month(&mut self) {
self.first_day_of_month = false;
self.reset_hour();
}
pub fn hour_lower_bound(&mut self) -> Ordinal {
if self.first_hour {
self.first_hour = false;
return self.initial_datetime.hour() as u32;
}
Hours::inclusive_min()
}
pub fn reset_hour(&mut self) {
self.first_hour = false;
self.reset_minute();
}
pub fn minute_lower_bound(&mut self) -> Ordinal {
if self.first_minute {
self.first_minute = false;
return self.initial_datetime.minute() as u32;
}
Minutes::inclusive_min()
}
pub fn reset_minute(&mut self) {
self.first_minute = false;
self.reset_second();
}
pub fn second_lower_bound(&mut self) -> Ordinal {
if self.first_second {
self.first_second = false;
return self.initial_datetime.second() as u32;
}
Seconds::inclusive_min()
}
pub fn reset_second(&mut self) {
self.first_second = false;
}
}
pub struct PrevFromQuery {
initial_datetime: Zoned,
first_month: bool,
first_day_of_month: bool,
first_hour: bool,
first_minute: bool,
first_second: bool,
}
impl PrevFromQuery {
pub fn from(before: &Zoned) -> PrevFromQuery {
PrevFromQuery {
initial_datetime: before.clone().saturating_sub(ONE_SECOND),
first_month: true,
first_day_of_month: true,
first_hour: true,
first_minute: true,
first_second: true,
}
}
pub fn year_upper_bound(&self) -> Ordinal {
self.initial_datetime.year() as u32
}
pub fn month_upper_bound(&mut self) -> Ordinal {
if self.first_month {
self.first_month = false;
return self.initial_datetime.month() as u32;
}
Months::inclusive_max()
}
pub fn reset_month(&mut self) {
self.first_month = false;
self.reset_day_of_month();
}
pub fn day_of_month_upper_bound(&mut self) -> Ordinal {
if self.first_day_of_month {
self.first_day_of_month = false;
return self.initial_datetime.day() as u32;
}
DaysOfMonth::inclusive_max()
}
pub fn reset_day_of_month(&mut self) {
self.first_day_of_month = false;
self.reset_hour();
}
pub fn hour_upper_bound(&mut self) -> Ordinal {
if self.first_hour {
self.first_hour = false;
return self.initial_datetime.hour() as u32;
}
Hours::inclusive_max()
}
pub fn reset_hour(&mut self) {
self.first_hour = false;
self.reset_minute();
}
pub fn minute_upper_bound(&mut self) -> Ordinal {
if self.first_minute {
self.first_minute = false;
return self.initial_datetime.minute() as u32;
}
Minutes::inclusive_max()
}
pub fn reset_minute(&mut self) {
self.first_minute = false;
self.reset_second();
}
pub fn second_upper_bound(&mut self) -> Ordinal {
if self.first_second {
self.first_second = false;
return self.initial_datetime.second() as u32;
}
Seconds::inclusive_max()
}
pub fn reset_second(&mut self) {
self.first_second = false;
}
}