Get rid of nom
This commit is contained in:
parent
afa708960c
commit
2ef7fd0f5e
4 changed files with 0 additions and 219 deletions
30
Cargo.lock
generated
30
Cargo.lock
generated
|
|
@ -27,29 +27,6 @@ version = "0.2.106"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "minimal-lexical"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom"
|
|
||||||
version = "7.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
"minimal-lexical",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
|
|
@ -85,15 +62,8 @@ name = "today"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"nom",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
version = "0.10.0+wasi-snapshot-preview1"
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,3 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
nom = "7.1.0"
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
mod commands;
|
mod commands;
|
||||||
mod parse;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
|
|
||||||
187
src/parse.rs
187
src/parse.rs
|
|
@ -1,187 +0,0 @@
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use chrono::{Duration, NaiveDate, NaiveTime};
|
|
||||||
use nom::branch::Alt;
|
|
||||||
use nom::bytes::complete::{take_while1, take_while_m_n};
|
|
||||||
use nom::character::complete::{char, digit1, newline};
|
|
||||||
use nom::combinator::{eof, fail, map_opt, map_res, opt, value};
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::{IResult, Parser};
|
|
||||||
|
|
||||||
use crate::commands::Delta;
|
|
||||||
|
|
||||||
fn line_ending(i: &str) -> IResult<&str, ()> {
|
|
||||||
(newline.map(|_| ()), eof.map(|_| ())).choice(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn title(i: &str) -> IResult<&str, &str> {
|
|
||||||
terminated(take_while1(|c| c != '\n'), line_ending)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn number<N: FromStr>(i: &str) -> IResult<&str, N> {
|
|
||||||
map_res(digit1, str::parse)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fixed_width_number<N: FromStr, const W: usize>(i: &str) -> IResult<&str, N> {
|
|
||||||
map_res(
|
|
||||||
take_while_m_n(W, W, |c: char| c.is_ascii_digit()),
|
|
||||||
str::parse,
|
|
||||||
)(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn date(i: &str) -> IResult<&str, NaiveDate> {
|
|
||||||
let (i, year) = number::<i32>(i)?;
|
|
||||||
let (i, _) = char('-')(i)?;
|
|
||||||
let (i, month) = fixed_width_number::<u32, 2>(i)?;
|
|
||||||
let (i, _) = char('-')(i)?;
|
|
||||||
let (i, day) = fixed_width_number::<u32, 2>(i)?;
|
|
||||||
match NaiveDate::from_ymd_opt(year, month, day) {
|
|
||||||
Some(date) => Ok((i, date)),
|
|
||||||
None => fail(i),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn time(i: &str) -> IResult<&str, NaiveTime> {
|
|
||||||
let (i, hour) = fixed_width_number::<u32, 2>(i)?;
|
|
||||||
let (i, _) = char(':')(i)?;
|
|
||||||
let (i, min) = fixed_width_number::<u32, 2>(i)?;
|
|
||||||
if hour < 24 && min < 60 {
|
|
||||||
Ok((i, NaiveTime::from_hms(hour, min, 0)))
|
|
||||||
} else {
|
|
||||||
fail(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn single_delta<const C: char>(i: &str) -> IResult<&str, i32> {
|
|
||||||
let (i, sign) = (value(1, char('+')), value(-1, char('-'))).choice(i)?;
|
|
||||||
let (i, amount) = opt(number::<i32>)(i)?;
|
|
||||||
let amount = amount.unwrap_or(1);
|
|
||||||
Ok((i, sign * amount))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn opt_single_delta<const C: char>(i: &str) -> IResult<&str, i32> {
|
|
||||||
let (i, delta) = opt(single_delta::<C>)(i)?;
|
|
||||||
let delta = delta.unwrap_or(0);
|
|
||||||
Ok((i, delta))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delta(i: &str) -> IResult<&str, Delta> {
|
|
||||||
// TODO Require at least one field?
|
|
||||||
let (i, years) = opt_single_delta::<'y'>(i)?;
|
|
||||||
let (i, months) = opt_single_delta::<'m'>(i)?;
|
|
||||||
let (i, weeks) = opt_single_delta::<'w'>(i)?;
|
|
||||||
let (i, days) = opt_single_delta::<'d'>(i)?;
|
|
||||||
let (i, hours) = opt_single_delta::<'h'>(i)?;
|
|
||||||
let (i, minutes) = opt_single_delta::<'m'>(i)?;
|
|
||||||
Ok((
|
|
||||||
i,
|
|
||||||
Delta {
|
|
||||||
years,
|
|
||||||
months,
|
|
||||||
weeks,
|
|
||||||
days,
|
|
||||||
hours,
|
|
||||||
minutes,
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_line_ending() {
|
|
||||||
assert_eq!(line_ending("\n"), Ok(("", ())));
|
|
||||||
assert_eq!(line_ending("\nbla"), Ok(("bla", ())));
|
|
||||||
assert_eq!(line_ending("\n\n"), Ok(("\n", ())));
|
|
||||||
assert_eq!(line_ending(""), Ok(("", ())));
|
|
||||||
|
|
||||||
assert!(line_ending("bla").is_err());
|
|
||||||
assert!(line_ending("\r").is_err());
|
|
||||||
assert!(line_ending("\r\n").is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_title() {
|
|
||||||
assert_eq!(title("foo bar\nbaz"), Ok(("baz", "foo bar")));
|
|
||||||
assert_eq!(title("foo bar\n"), Ok(("", "foo bar")));
|
|
||||||
assert_eq!(title("foo bar"), Ok(("", "foo bar")));
|
|
||||||
assert_eq!(title(" \nbla"), Ok(("bla", " ")));
|
|
||||||
assert_eq!(
|
|
||||||
title("!\"§$%&/()'<>[]{}_:;.,-=\nbla"),
|
|
||||||
Ok(("bla", "!\"§$%&/()'<>[]{}_:;.,-="))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(title("\nxyz").is_err());
|
|
||||||
assert!(title("").is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_number() {
|
|
||||||
assert_eq!(number::<u32>("012345abc"), Ok(("abc", 12345)));
|
|
||||||
assert_eq!(number::<u8>("255"), Ok(("", 255)));
|
|
||||||
assert_eq!(number::<i64>("0x3f"), Ok(("x3f", 0)));
|
|
||||||
|
|
||||||
assert!(number::<u8>("256").is_err());
|
|
||||||
assert!(number::<i32>("xyz").is_err());
|
|
||||||
assert!(number::<i8>("").is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fixed_width_number() {
|
|
||||||
assert_eq!(
|
|
||||||
fixed_width_number::<u32, 2>("012345abc"),
|
|
||||||
Ok(("2345abc", 1))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
fixed_width_number::<u32, 3>("012345abc"),
|
|
||||||
Ok(("345abc", 12))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
fixed_width_number::<u32, 6>("012345abc"),
|
|
||||||
Ok(("abc", 12345))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(fixed_width_number::<u8, 0>("012345abc").is_err());
|
|
||||||
assert!(fixed_width_number::<u8, 6>("012345abc").is_err());
|
|
||||||
assert!(fixed_width_number::<u8, 3>("14x").is_err());
|
|
||||||
assert!(fixed_width_number::<i8, 4>("").is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_date() {
|
|
||||||
assert_eq!(
|
|
||||||
date("2021-11-06"),
|
|
||||||
Ok(("", NaiveDate::from_ymd(2021, 11, 6)))
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
date("2021-11-0678"),
|
|
||||||
Ok(("78", NaiveDate::from_ymd(2021, 11, 6)))
|
|
||||||
);
|
|
||||||
assert_eq!(date("0-01-01"), Ok(("", NaiveDate::from_ymd(0, 1, 1))));
|
|
||||||
assert_eq!(
|
|
||||||
date("2020-02-29"),
|
|
||||||
Ok(("", NaiveDate::from_ymd(2020, 2, 29)))
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(date("2021-11-6").is_err());
|
|
||||||
assert!(date("0000-00-00").is_err());
|
|
||||||
assert!(date("2021-02-29").is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_time() {
|
|
||||||
assert_eq!(time("12:34"), Ok(("", NaiveTime::from_hms(12, 34, 0))));
|
|
||||||
assert_eq!(time("00:00"), Ok(("", NaiveTime::from_hms(0, 0, 0))));
|
|
||||||
assert_eq!(time("23:59"), Ok(("", NaiveTime::from_hms(23, 59, 0))));
|
|
||||||
assert_eq!(time("02:04:06"), Ok((":06", NaiveTime::from_hms(2, 4, 0))));
|
|
||||||
|
|
||||||
assert!(time("abc").is_err());
|
|
||||||
assert!(time("24:23").is_err());
|
|
||||||
assert!(time("12:60").is_err());
|
|
||||||
assert!(time("12-34").is_err());
|
|
||||||
assert!(time("2:34").is_err());
|
|
||||||
assert!(time("12:3").is_err());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue