|
@@ -1,8 +1,8 @@
|
|
|
use crate::data::{
|
|
|
- AccountName, DataError, Decimal, SourceFile, Span, Spanned, UnitName, spec::SpecRoot,
|
|
|
+ AccountName, DataError, Datestamp, Decimal, SourceFile, Span, Spanned, UnitName, spec::SpecRoot,
|
|
|
};
|
|
|
|
|
|
-use super::{Balance, Transaction, LedgerEntry};
|
|
|
+use super::{Change, Transaction, LedgerEntry};
|
|
|
|
|
|
use chumsky::{prelude::*, text::inline_whitespace};
|
|
|
|
|
@@ -23,7 +23,7 @@ fn ledger_parser<'a>() -> impl Parser<
|
|
|
.map(|v: &str| v.parse::<usize>().unwrap());
|
|
|
|
|
|
let datestamp = group((int, just('-').ignored(), int, just('-').ignored(), int))
|
|
|
- .map(|(y, _, m, _, d)| (y as u16, m as u8, d as u8));
|
|
|
+ .map(|(y, _, m, _, d)| Datestamp { year: y as u16, month: m as u8, day: d as u8 });
|
|
|
|
|
|
let mark = |m| just(m).padded_by(inline_whitespace());
|
|
|
|
|
@@ -47,11 +47,15 @@ fn ledger_parser<'a>() -> impl Parser<
|
|
|
))
|
|
|
});
|
|
|
|
|
|
- let balance = group((
|
|
|
+ let change = group((
|
|
|
mark('-'),
|
|
|
none_of(": \n\t").repeated().to_slice().map_with(|v, e| Spanned(AccountName::new(v), e.span())),
|
|
|
mark(':'),
|
|
|
decimal,
|
|
|
+ choice((
|
|
|
+ mark('=').ignore_then(decimal).map(Some),
|
|
|
+ empty().map(|_| None)
|
|
|
+ )),
|
|
|
choice((
|
|
|
inline_whitespace()
|
|
|
.at_least(1)
|
|
@@ -62,7 +66,7 @@ fn ledger_parser<'a>() -> impl Parser<
|
|
|
))
|
|
|
.then_ignore(chumsky::text::newline()),
|
|
|
))
|
|
|
- .try_map_with(|(_, acc, _, amount, unit, ), e| {
|
|
|
+ .try_map_with(|(_, acc, _, amount, balance, unit, ), e| {
|
|
|
let span = e.span();
|
|
|
let spec: &mut chumsky::extra::SimpleState<&SpecRoot> = e.state();
|
|
|
|
|
@@ -89,9 +93,10 @@ fn ledger_parser<'a>() -> impl Parser<
|
|
|
return Err(chumsky::error::Rich::custom(unit.span(), format!("no such unit '{unit}' found")))
|
|
|
}
|
|
|
|
|
|
- Ok(Spanned::new(Balance {
|
|
|
+ Ok(Spanned::new(Change {
|
|
|
account: acc,
|
|
|
amount,
|
|
|
+ balance,
|
|
|
unit,
|
|
|
}, span))
|
|
|
});
|
|
@@ -117,17 +122,17 @@ fn ledger_parser<'a>() -> impl Parser<
|
|
|
.then_ignore(chumsky::text::newline()),
|
|
|
empty().map(|_| vec![]),
|
|
|
)),
|
|
|
- balance.repeated().at_least(1).collect(),
|
|
|
+ change.repeated().at_least(1).collect(),
|
|
|
chumsky::text::whitespace(),
|
|
|
))
|
|
|
.map_with(
|
|
|
- |(_, datestamp, _, _, title, _, annotations, balances, _), e| {
|
|
|
+ |(_, datestamp, _, _, title, _, annotations, changes, _), e| {
|
|
|
LedgerEntry::Transaction(Spanned::new(
|
|
|
Transaction {
|
|
|
datestamp,
|
|
|
title: (!title.is_empty()).then_some(title),
|
|
|
annotations,
|
|
|
- balances,
|
|
|
+ changes,
|
|
|
},
|
|
|
e.span(),
|
|
|
))
|