use std::path::PathBuf; use std::result; use chrono::NaiveDate; use pest::error::ErrorVariant; use pest::iterators::Pair; use pest::prec_climber::{Assoc, Operator, PrecClimber}; use pest::{Parser, Span}; use super::commands::{ Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, Expr, File, FormulaSpec, Note, Spec, Task, Time, Var, Weekday, WeekdaySpec, }; #[derive(pest_derive::Parser)] #[grammar = "files/grammar.pest"] struct TodayfileParser; pub type Error = pest::error::Error; pub type Result = result::Result; fn error>(span: Span, message: S) -> Error { Error::new_from_span( ErrorVariant::CustomError { message: message.into(), }, span, ) } fn fail, T>(span: Span, message: S) -> Result { Err(error(span, message)) } fn parse_number(p: Pair) -> i32 { assert_eq!(p.as_rule(), Rule::number); p.as_str().parse().unwrap() } fn parse_title(p: Pair) -> String { assert_eq!(p.as_rule(), Rule::title); let p = p.into_inner().next().unwrap(); assert_eq!(p.as_rule(), Rule::rest_some); p.as_str().trim().to_string() } fn parse_datum(p: Pair) -> Result { assert_eq!(p.as_rule(), Rule::datum); let span = p.as_span(); let mut p = p.into_inner(); let year = p.next().unwrap().as_str().parse().unwrap(); let month = p.next().unwrap().as_str().parse().unwrap(); let day = p.next().unwrap().as_str().parse().unwrap(); assert_eq!(p.next(), None); match NaiveDate::from_ymd_opt(year, month, day) { Some(date) => Ok(date), None => fail(span, "invalid date"), } } fn parse_time(p: Pair) -> Result