use chrono::NaiveDateTime;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Window {
pub start: NaiveDateTime,
pub end: NaiveDateTime,
}
pub struct WindowBuilder {
pub start: Option<NaiveDateTime>,
pub end: Option<NaiveDateTime>,
pub length: Option<WindowLength>,
}
pub enum WindowLength {
Seconds(i64),
Minutes(i64),
Hours(i64),
Days(i64),
Weeks(i64),
Months(i64),
Years(i64),
}
impl WindowBuilder {
pub fn new() -> Self {
Self {
start: None,
end: None,
length: None,
}
}
pub fn start(mut self, start: NaiveDateTime) -> Self {
self.start = Some(start);
self
}
pub fn end(mut self, end: NaiveDateTime) -> Self {
self.end = Some(end);
self
}
pub fn length(mut self, length: WindowLength) -> Self {
self.length = Some(length);
self
}
pub fn build(self) -> Result<Window, String> {
if self.start.is_some() && self.end.is_some() {
if self.start.unwrap() > self.end.unwrap() {
return Err("Start time must be before end time".to_string());
}
return Ok(Window {
start: self.start.unwrap(),
end: self.end.unwrap(),
});
}
if self.start.is_some() && self.length.is_some() {
let start = self.start.unwrap();
let length = self.length.unwrap();
let end = match length {
WindowLength::Seconds(s) => start + chrono::Duration::seconds(s),
WindowLength::Minutes(m) => start + chrono::Duration::minutes(m),
WindowLength::Hours(h) => start + chrono::Duration::hours(h),
WindowLength::Days(d) => start + chrono::Duration::days(d),
WindowLength::Weeks(w) => start + chrono::Duration::weeks(w),
WindowLength::Months(m) => start + chrono::Duration::days(m * 30),
WindowLength::Years(y) => start + chrono::Duration::days(y * 365),
};
return Ok(Window { start, end });
}
if self.end.is_some() && self.length.is_some() {
let end = self.end.unwrap();
let length = self.length.unwrap();
let start = match length {
WindowLength::Seconds(s) => end - chrono::Duration::seconds(s),
WindowLength::Minutes(m) => end - chrono::Duration::minutes(m),
WindowLength::Hours(h) => end - chrono::Duration::hours(h),
WindowLength::Days(d) => end - chrono::Duration::days(d),
WindowLength::Weeks(w) => end - chrono::Duration::weeks(w),
WindowLength::Months(m) => end - chrono::Duration::days(m * 30),
WindowLength::Years(y) => end - chrono::Duration::days(y * 365),
};
return Ok(Window { start, end });
}
if self.length.is_some() {
let now = chrono::Local::now().naive_local();
let length = self.length.unwrap();
let start = match length {
WindowLength::Seconds(s) => now - chrono::Duration::seconds(s),
WindowLength::Minutes(m) => now - chrono::Duration::minutes(m),
WindowLength::Hours(h) => now - chrono::Duration::hours(h),
WindowLength::Days(d) => now - chrono::Duration::days(d),
WindowLength::Weeks(w) => now - chrono::Duration::weeks(w),
WindowLength::Months(m) => now - chrono::Duration::days(m * 30),
WindowLength::Years(y) => now - chrono::Duration::days(y * 365),
};
return Ok(Window { start, end: now });
}
Err("Must provide either start and end or start and length".to_string())
}
}
impl Default for WindowBuilder {
fn default() -> Self {
Self::new()
}
}