use anyhow::{bail, format_err, Result}; use chrono::{DateTime, Local, LocalResult, NaiveDate, TimeZone}; #[derive(Debug)] pub(super) struct Range { pub start: DateTime, pub end: DateTime, } pub(super) fn try_create_range>(date: S) -> Result { Ok(Range { start: create_day_bound(&date, 0, 0, 0)?, end: create_day_bound(date, 23, 59, 59)?, }) } fn create_day_bound>( day: S, hour: u32, minute: u32, second: u32, ) -> Result> { let ts: Vec<&str> = day.as_ref().split("-").collect(); if ts.len() != 3 { bail!("Invalid date format! {}", day.as_ref()) } let (year, month, day) = if let [year, month, day, ..] = &ts[..] { (year, month, day) } else { bail!("Invalid date format! {}", day.as_ref()) }; let b = Local.from_local_datetime( &NaiveDate::from_ymd_opt(year.parse()?, month.parse()?, day.parse()?) .ok_or_else(|| format_err!("Invalid date!"))? .and_hms_opt(hour, minute, second) .ok_or_else(|| format_err!("Invalid time!"))?, ); if let LocalResult::Single(b) = b { Ok(b) } else { bail!("Cannot construct day boundary!") } }