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
use nom::{
    bytes::complete::tag,
    character::complete::space1,
    combinator::map,
    sequence::{preceded, separated_pair, tuple},
    IResult,
};

use crate::{account, date::date, Account, Date};

/// Open account directive
#[derive(Debug, Clone)]
pub struct Open<'a> {
    date: Date,
    account: Account<'a>,
}

impl<'a> Open<'a> {
    /// Date at which the account is open
    #[must_use]
    pub fn date(&self) -> Date {
        self.date
    }

    /// Account being open
    #[must_use]
    pub fn account(&self) -> &Account<'a> {
        &self.account
    }
}

pub(crate) fn open(input: &str) -> IResult<&str, Open<'_>> {
    map(
        separated_pair(
            date,
            space1,
            preceded(tuple((tag("open"), space1)), account::account),
        ),
        |(date, account)| Open { date, account },
    )(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"]));
    }
}