//! The definition of the "kairos" syntax, for parsing user input into TimeType objects
//!
//! The syntax itself is described in the grammar.rustpeg file.
//! Here goes a documentation on the syntax
//!
//! # Syntax
//!
//! ## Units
//!
//! UnitSec = "second" | "seconds" | "sec" | "secs" | "s"
//! UnitMin = "minute" | "minutes" | "min" | "mins"
//! UnitHr = "hour" | "hours" | "hr" | "hrs"
//! UnitDay = "day" | "days" | "d"
//! UnitWeek = "week" | "weeks" | "w"
//! UnitMonth = "month" | "months" |
//! UnitYear = "year" | "years" | "yrs"
//! Unit = UnitSec | UnitMin | UnitHr | UnitDay | UnitWeek | UnitMonth | UnitYear
//!
//! ## Operators
//!
//! Operator = "+" | "-"
//!
//! ## Intermediate syntax nodes
//!
//! Amount = "<Number><Unit>"
//!
//! TextIterSpec = "secondly" | "minutely" | "hourly" | "daily" | "weekly" | "monthly" | "yearly"
//! Iterspec = TextIterSpec | "every" <Number><Unit>
//!
//! ## User-facing syntax nodes
//!
//! AmountExpr = <Amount> (<Operator> <AmountExpr>)?
//! ExactDate = "today" | "yesterday" | "tomorrow" | <Iso8601>
//! Date = <ExactDate> (<Operator> <AmountExpr>)?
//! Iterator = <Date> <Iterspec> ("until" <ExactDate> | <number> "times")?
//!
//! # Warning
//!
//! This module is not intended for public use... it is still public, so you can use it, but you
//! should know that these interfaces are considered private and I will not follow semver and
//! update the minor or major semver numbers of the interface of this module changes.
//!
//! Be warned!
//!
use nom::{IResult, space, alpha, alphanumeric, digit};
use std::str;
use std::str::FromStr;
use chrono::NaiveDate;
use timetype;
use iter;
use error;
named!(integer<i64>, alt!(
map_res!(
map_res!(
ws!(digit),
str::from_utf8
),
FromStr::from_str
)
));
// WARNING: Order is important here. Long tags first, shorter tags later
named!(unit_parser<Unit>, alt_complete!(
tag!("seconds") => { |_| Unit::Second } |
tag!("second") => { |_| Unit::Second } |
tag!("secs") => { |_| Unit::Second } |
tag!("sec") => { |_| Unit::Second } |
tag!("s") => { |_| Unit::Second } |
tag!("minutes") => { |_| Unit::Minute } |
tag!("minute") => { |_| Unit::Minute } |
tag!("mins") => { |_| Unit::Minute } |
tag!("min") => { |_| Unit::Minute } |
tag!("hours") => { |_| Unit::Hour } |
tag!("hour") => { |_| Unit::Hour } |
tag!("hrs") => { |_| Unit::Hour } |
tag!("hr") => { |_| Unit::Hour } |
tag!("days") => { |_| Unit::Day } |
tag!("day") => { |_| Unit::Day } |
tag!("d") => { |_| Unit::Day } |
tag!("weeks") => { |_| Unit::Week } |
tag!("week") => { |_| Unit::Week } |
tag!("w") => { |_| Unit::Week } |
tag!("months") => { |_| Unit::Month } |
tag!("month") => { |_| Unit::Month } |
tag!("years") => { |_| Unit::Year } |
tag!("year") => { |_| Unit::Year } |
tag!("yrs") => { |_| Unit::Year }
));
#[derive(Debug, PartialEq, Eq)]
pub enum Unit {
Second,
Minute,
Hour,
Day,
Week,
Month,
Year,
}
named!(operator_parser<Operator>, alt!(
tag!("+") => { |_| Operator::Plus } |
tag!("-") => { |_| Operator::Minus }
));
#[derive(Debug, PartialEq, Eq)]
pub enum Operator {
Plus,
Minus,
}
named!(amount_parser<Amount>, do_parse!(
number: integer >>
unit : unit_parser >>
(Amount(number, unit))
));
#[derive(Debug, PartialEq, Eq)]
pub struct Amount(i64, Unit);
impl Into<timetype::TimeType> for Amount {
fn into(