use std::path::Path; use std::result; use chrono::NaiveDate; use pest::error::{Error, ErrorVariant}; use pest::iterators::Pair; use pest::prec_climber::{Assoc, Operator, PrecClimber}; use pest::{Parser, Span}; use crate::commands::{ Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, Expr, FormulaSpec, Note, Spec, Task, Time, Var, Weekday, WeekdaySpec, }; #[derive(pest_derive::Parser)] #[grammar = "parse/todayfile.pest"] struct TodayfileParser; 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_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().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