rustledger_plugin/native/plugins/
close_tree.rs1use crate::types::{
4 CloseData, DirectiveData, DirectiveWrapper, PluginInput, PluginOp, PluginOutput,
5};
6
7use super::super::NativePlugin;
8
9pub struct CloseTreePlugin;
14
15impl NativePlugin for CloseTreePlugin {
16 fn name(&self) -> &'static str {
17 "close_tree"
18 }
19
20 fn description(&self) -> &'static str {
21 "Close descendant accounts automatically"
22 }
23
24 fn process(&self, input: PluginInput) -> PluginOutput {
25 use std::collections::HashSet;
26
27 let mut all_accounts: HashSet<String> = HashSet::new();
29 for wrapper in &input.directives {
30 if let DirectiveData::Open(data) = &wrapper.data {
31 all_accounts.insert(data.account.clone());
32 }
33 if let DirectiveData::Transaction(txn) = &wrapper.data {
34 for posting in &txn.postings {
35 all_accounts.insert(posting.account.clone());
36 }
37 }
38 }
39
40 let mut closed_parents: Vec<(String, String)> = Vec::new(); for wrapper in &input.directives {
43 if let DirectiveData::Close(data) = &wrapper.data {
44 closed_parents.push((data.account.clone(), wrapper.date.clone()));
45 }
46 }
47
48 let mut already_closed: HashSet<String> = HashSet::new();
50 for wrapper in &input.directives {
51 if let DirectiveData::Close(data) = &wrapper.data {
52 already_closed.insert(data.account.clone());
53 }
54 }
55
56 let mut ops: Vec<PluginOp> = (0..input.directives.len()).map(PluginOp::Keep).collect();
58
59 let mut inserted_closes: HashSet<String> = HashSet::new();
62
63 for (parent, close_date) in &closed_parents {
64 let prefix = format!("{parent}:");
65 for account in &all_accounts {
66 if account.starts_with(&prefix)
67 && !already_closed.contains(account)
68 && !inserted_closes.contains(account)
69 {
70 inserted_closes.insert(account.clone());
71 ops.push(PluginOp::Insert(DirectiveWrapper {
72 directive_type: "close".to_string(),
73 date: close_date.clone(),
74 filename: None, lineno: None,
76 data: DirectiveData::Close(CloseData {
77 account: account.clone(),
78 metadata: vec![],
79 }),
80 }));
81 }
82 }
83 }
84
85 PluginOutput {
88 ops,
89 errors: Vec::new(),
90 }
91 }
92}