use crate::error::{Error, Result}; use crate::iter::Iter; use crate::{time, token}; use proc_macro::Group; use std::fmt::{self, Display}; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct Date { pub year: u16, pub month: u8, pub day: u8, } impl Display for Date { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!( formatter, "{:04}-{:02}-{:02}", self.year, self.month, self.day, ) } } pub fn parse(paren: Group, iter: Iter) -> Result { try_parse(iter).map_err(|_| { let msg = format!("expected nightly date, like {}", time::today()); Error::group(paren, msg) }) } fn try_parse(iter: Iter) -> Result { let year = token::parse_literal(iter).map_err(drop)?; token::parse_punct(iter, '-').map_err(drop)?; let month = token::parse_literal(iter).map_err(drop)?; token::parse_punct(iter, '-').map_err(drop)?; let day = token::parse_literal(iter).map_err(drop)?; let year = year.to_string().parse::().map_err(drop)?; let month = month.to_string().parse::().map_err(drop)?; let day = day.to_string().parse::().map_err(drop)?; if year >= 3000 || month > 12 || day > 31 { return Err(()); } Ok(Date { year: year as u16, month: month as u8, day: day as u8, }) }