1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use nom::{
bytes::complete::tag,
character::complete::{char, space0, space1},
combinator::map,
multi::separated_list0,
sequence::{preceded, separated_pair, tuple},
IResult,
};
use crate::amount;
use crate::{account, date::date, Account, Date};
#[derive(Debug, Clone)]
pub struct Open<'a> {
date: Date,
account: Account<'a>,
currencies: Vec<&'a str>,
}
impl<'a> Open<'a> {
#[must_use]
pub fn date(&self) -> Date {
self.date
}
#[must_use]
pub fn account(&self) -> &Account<'a> {
&self.account
}
#[must_use]
pub fn currencies(&self) -> &[&'a str] {
&self.currencies
}
}
pub(crate) fn open(input: &str) -> IResult<&str, Open<'_>> {
map(
separated_pair(
date,
space1,
tuple((
preceded(tuple((tag("open"), space1)), account::account),
separated_list0(char(','), preceded(space0, amount::currency)),
)),
),
|(date, (account, currencies))| Open {
date,
account,
currencies,
},
)(input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn simple_open_directive() {
let input = "2022-10-14 open Assets:A";
let (_, open) = open(input).expect("should successfuly parse the input");
assert_eq!(open.date(), Date::new(2022, 10, 14));
assert_eq!(open.account(), &Account::new(account::Type::Assets, ["A"]));
}
}