From 75793e4bdf65129a7158bf0c541a7528e1733856 Mon Sep 17 00:00:00 2001 From: Jonathan Cornaz Date: Sun, 11 Sep 2022 10:01:53 +0200 Subject: [PATCH] feat: ignore unknown directives --- src/directive.rs | 51 ++++++++++++++++++++++++++++--- src/lib.rs | 5 ++- tests/examples/comments.beancount | 5 +++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/directive.rs b/src/directive.rs index 822edfc..154b007 100644 --- a/src/directive.rs +++ b/src/directive.rs @@ -1,4 +1,11 @@ -use nom::{character::complete::space1, combinator::map, sequence::separated_pair, IResult}; +use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{line_ending, not_line_ending, one_of, space1}, + combinator::{map, not, opt, value}, + sequence::{separated_pair, tuple}, + IResult, +}; use crate::{ date::date, @@ -12,21 +19,57 @@ pub enum Directive<'a> { Transaction(Transaction<'a>), } -pub(crate) fn directive(input: &str) -> IResult<&str, (Date, Directive<'_>)> { - separated_pair(date, space1, map(transaction, Directive::Transaction))(input) +pub(crate) fn directive(input: &str) -> IResult<&str, (Date, Option>)> { + separated_pair( + date, + space1, + alt(( + map(map(transaction, Directive::Transaction), Some), + value( + None, + tuple(( + not(tag("txn")), + not(one_of("*!")), + not_line_ending, + opt(line_ending), + )), + ), + )), + )(input) } #[cfg(test)] mod tests { use super::*; + use rstest::rstest; #[test] fn transaction() { let input = r#"2022-09-10 txn "My transaction""#; let (_, (date, directive)) = directive(input).expect("should successfully parse directive"); assert_eq!(date, Date::new(2022, 9, 10)); - match directive { + match directive.expect("should recognize the directive") { Directive::Transaction(trx) => assert_eq!(trx.narration(), Some("My transaction")), } } + + #[rstest] + #[case("2022-09-11 whatisthis \"hello\"", "")] + #[case("2022-09-11 whatisthis \"hello\"\ntest", "test")] + fn unkown_directive(#[case] input: &str, #[case] expected_rest: &str) { + let (rest, _) = directive(input).expect("should successfully parse the directive"); + assert_eq!(rest, expected_rest); + } + + #[rstest] + fn invalid( + #[values( + "2022-09-11 txn that is incorrect", + "2022-09-11 * that is incorrect", + "2022-09-11 ! that is incorrect" + )] + input: &str, + ) { + assert!(directive(input).is_err()); + } } diff --git a/src/lib.rs b/src/lib.rs index aea2c49..bf438dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,5 +57,8 @@ impl<'a> Iterator for Parser<'a> { } fn next(input: &str) -> IResult<&str, Option<(Date, Directive<'_>)>> { - alt((map(directive, Some), value(None, comment_line)))(input) + alt(( + map(directive, |(date, directive)| directive.map(|d| (date, d))), + value(None, comment_line), + ))(input) } diff --git a/tests/examples/comments.beancount b/tests/examples/comments.beancount index c0dc17b..ef0d57c 100644 --- a/tests/examples/comments.beancount +++ b/tests/examples/comments.beancount @@ -1,8 +1,13 @@ * Banking ** Bank of America +2003-01-05 open Assets:US:BofA:Checking +2003-01-05 open Assets:US:BofA:Savings + ;; Transactions follow … ** TD Bank +2006-03-15 open Assets:US:TD:Cash + ;; More transactions follow …