use chrono::prelude::*;
use regex::Regex;
const FORMAT: &'static str = "%Y-%m-%d";
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct JustDate(Date<Utc>);
impl JustDate {
#[allow(dead_code)]
pub fn date(&self) -> Date<Utc> {
self.0
}
pub fn utc_now() -> Self {
JustDate(Utc::now().date())
}
pub fn format(&self) -> String {
self.0.format(FORMAT).to_string()
}
pub fn parse(input: &String) -> Option<Self> {
if input == "today" {
return Some(Self::utc_now());
}
match NaiveDate::parse_from_str(input.as_str(), FORMAT) {
Ok(t) => {
let date = Utc.ymd(t.year(), t.month(), t.day());
Some(JustDate(date))
},
Err(_) => JustDate::parse_relative(input),
}
}
fn parse_relative(input: &String) -> Option<Self> {
let exp = Regex::new(r"(?P<days>\d+)d").unwrap();
match exp.captures(input.as_str()) {
Some(cap) => {
match String::from(&cap["days"]).parse::<i64>() {
Ok(days) => {
let now = Utc::now().date();
match now.checked_sub_signed(chrono::Duration::days(days)) {
Some(date) => Some(JustDate(date)),
None => None,
}
},
Err(_) => None,
}
},
None => None,
}
}
}