okane_core/report/
context.rs1use bumpalo::Bump;
2
3use crate::report::AccountAggregate;
4
5use super::account::{Account, AccountStore, AccountTree};
6use super::commodity::{CommodityStore, CommodityTag};
7
8pub struct ReportContext<'ctx> {
10 pub(super) arena: &'ctx Bump,
11 pub(super) accounts: AccountStore<'ctx>,
12 pub(super) account_tree: AccountTree<'ctx>,
13 pub(super) commodities: CommodityStore<'ctx>,
14}
15
16impl<'ctx> ReportContext<'ctx> {
17 pub fn new(arena: &'ctx Bump) -> Self {
19 let accounts = AccountStore::new(arena);
20 let account_tree = AccountTree::new(arena);
21 let commodities = CommodityStore::new(arena);
22 Self {
23 arena,
24 accounts,
25 account_tree,
26 commodities,
27 }
28 }
29
30 pub(super) fn all_accounts_unsorted(&self) -> impl Iterator<Item = Account<'ctx>> + '_ {
32 self.accounts.iter()
33 }
34 pub(super) fn all_accounts(&self) -> Vec<Account<'ctx>> {
36 let mut r: Vec<Account<'ctx>> = self.all_accounts_unsorted().collect();
37 r.sort_unstable_by_key(|x| x.as_str());
38 r
39 }
40
41 #[inline]
43 pub fn account(&self, value: &str) -> Option<Account<'ctx>> {
44 self.accounts.resolve(value)
45 }
46
47 #[inline]
49 pub fn account_aggregate(&self, value: &str) -> Option<AccountAggregate<'ctx>> {
50 match self.account(value) {
51 Some(v) => Some(AccountAggregate::Account(v)),
52 None => self
53 .account_tree
54 .resolve_ancestor(value)
55 .map(AccountAggregate::Ancestor),
56 }
57 }
58
59 #[inline]
61 pub fn commodity(&self, value: &str) -> Option<CommodityTag<'ctx>> {
62 self.commodities.resolve(value)
63 }
64
65 #[inline]
67 pub fn commodity_store(&self) -> &CommodityStore<'ctx> {
68 &self.commodities
69 }
70 #[inline]
72 pub fn commodity_store_mut(&mut self) -> &mut CommodityStore<'ctx> {
73 &mut self.commodities
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use pretty_assertions::assert_eq;
80
81 use super::*;
82
83 #[test]
84 fn context_all_accounts() {
85 let arena = Bump::new();
86 let mut ctx = ReportContext::new(&arena);
87 let want = vec![
88 ctx.accounts.ensure("Account 1"),
89 ctx.accounts.ensure("Account 2"),
90 ctx.accounts.ensure("Account 2:Sub account"),
91 ctx.accounts.ensure("Account 3"),
92 ctx.accounts.ensure("資産:りんご"),
95 ctx.accounts.ensure("資産:バナナ"),
96 ctx.accounts.ensure("資産:吉祥寺"),
97 ];
98
99 let got = ctx.all_accounts();
100
101 assert_eq!(want, got);
102 }
103
104 #[test]
105 fn context_sccount() {
106 let arena = Bump::new();
107 let mut ctx = ReportContext::new(&arena);
108 let a1 = ctx.accounts.ensure("Account 1");
109 let a3 = ctx.accounts.ensure("Account 3");
110
111 assert_eq!(Some(a1), ctx.account("Account 1"));
112 assert_eq!(None, ctx.account("Account 2"));
113 assert_eq!(Some(a3), ctx.account("Account 3"));
114 }
115}