pactole_core/models/mod.rs
1//! Domain entities used by Pactole journals.
2
3mod balance;
4mod declarations;
5mod names;
6mod transaction;
7
8pub use balance::{Amount, Balance};
9pub use declarations::{Close, Commodity, Open, Payee};
10pub use names::{AccountName, CommodityName, Metadata, MetadataKey};
11pub use transaction::{Posting, Transaction, TransactionStatus};
12
13// -------------------------------------------------
14// Journal structure
15// -------------------------------------------------
16
17/// A collection of top-level Pactole directives.
18#[derive(Debug, Clone, PartialEq)]
19pub struct Journal {
20 /// Directives in their current order. Validation returns a chronologically
21 /// sorted journal while preserving source order before validation.
22 pub entries: Vec<Entry>,
23}
24
25impl Journal {
26 /// Returns the directives in this journal in their current order.
27 pub fn entries(&self) -> &[Entry] {
28 &self.entries
29 }
30}
31
32/// A top-level directive in a Pactole journal.
33#[derive(Debug, Clone, PartialEq)]
34pub enum Entry {
35 /// Opens an account.
36 Open(Open),
37 /// Closes an account.
38 Close(Close),
39 /// Declares a commodity.
40 Commodity(Commodity),
41 /// Declares a known payee.
42 Payee(Payee),
43 /// Records a transaction and its postings.
44 Transaction(Transaction),
45 /// Asserts an account balance.
46 Balance(Balance),
47}
48
49impl Entry {
50 /// Returns the date this entry is recorded at, used to sort a journal
51 /// chronologically before validating it.
52 ///
53 /// Returns `None` for a [`Payee`] declaration, which carries no date
54 /// (see its doc comment): entries with no date sort before every
55 /// dated entry (a stable sort keeps their relative order), so a
56 /// payee is always known by the time any transaction is validated,
57 /// regardless of where in the file it was declared.
58 pub fn date(&self) -> Option<chrono::NaiveDate> {
59 match self {
60 Entry::Open(open) => Some(open.date),
61 Entry::Close(close) => Some(close.date),
62 Entry::Commodity(commodity) => Some(commodity.date),
63 Entry::Payee(_) => None,
64 Entry::Transaction(transaction) => Some(transaction.date),
65 Entry::Balance(balance) => Some(balance.date),
66 }
67 }
68}