Skip to content

Commit

Permalink
internal: finish chumsky posting parser
Browse files Browse the repository at this point in the history
  • Loading branch information
jcornaz committed Mar 3, 2024
1 parent f9ab31b commit d7c9d03
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub(crate) mod chumsky {

use chumsky::prelude::*;

fn map<D: Decimal + 'static>() -> impl ChumskyParser<HashMap<Key, Value<D>>> {
pub(crate) fn map<D: Decimal + 'static>() -> impl ChumskyParser<HashMap<Key, Value<D>>> {
entry().padded().repeated().collect().labelled("metadata")
}

Expand Down
38 changes: 27 additions & 11 deletions src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,6 @@ fn cost<D: Decimal>(input: Span<'_>) -> IResult<'_, Cost<D>> {

#[cfg(test)]
mod chumsky {
use std::collections::HashMap;

use crate::{ChumskyParser, Decimal, Posting, PostingPrice};
use chumsky::{prelude::*, text::whitespace};

Expand All @@ -419,14 +417,22 @@ mod chumsky {
))
.or_not(),
)
.map(|((((flag, account), amount), cost), price)| Posting {
flag,
account,
amount,
cost,
price,
metadata: HashMap::new(),
})
.then(
crate::metadata::chumsky::map()
.padded()
.or_not()
.map(Option::unwrap_or_default),
)
.map(
|(((((flag, account), amount), cost), price), metadata)| Posting {
flag,
account,
amount,
cost,
price,
metadata,
},
)
}

fn cost<D: Decimal + 'static>() -> impl ChumskyParser<Cost<D>> {
Expand Down Expand Up @@ -463,7 +469,7 @@ mod chumsky {

#[cfg(test)]
mod tests {
use crate::{Amount, Date, PostingPrice};
use crate::{metadata, Amount, Date, PostingPrice};

use super::*;
use rstest::rstest;
Expand Down Expand Up @@ -513,6 +519,16 @@ mod chumsky {
assert_eq!(posting.cost, expected);
}

#[rstest]
fn should_parse_posting_metadata() {
let input = "Assets:Cash 10 CHF @ 40 PLN\n hello: \"world\"";
let posting: Posting<i32> = posting().parse(input).unwrap();
assert_eq!(
posting.metadata.get("hello"),
Some(&metadata::Value::String("world".into()))
);
}

#[rstest]
fn should_parse_empty_cost(#[values("{}", "{ }")] input: &str) {
let cost: Cost<i32> = cost().parse(input).unwrap();
Expand Down

0 comments on commit d7c9d03

Please sign in to comment.