rustledger_plugin/native/plugins/
one_commodity.rs1use crate::types::{DirectiveData, PluginError, PluginInput, PluginOutput};
4
5use super::super::NativePlugin;
6
7pub struct OneCommodityPlugin;
9
10impl NativePlugin for OneCommodityPlugin {
11 fn name(&self) -> &'static str {
12 "onecommodity"
13 }
14
15 fn description(&self) -> &'static str {
16 "Enforce single commodity per account"
17 }
18
19 fn process(&self, input: PluginInput) -> PluginOutput {
20 use std::collections::HashMap;
21
22 let mut account_currencies: HashMap<String, String> = HashMap::new();
24 let mut errors = Vec::new();
25
26 for wrapper in &input.directives {
27 if let DirectiveData::Transaction(txn) = &wrapper.data {
28 for posting in &txn.postings {
29 if let Some(units) = &posting.units {
30 if let Some(existing) = account_currencies.get(&posting.account) {
31 if existing != &units.currency {
32 errors.push(PluginError::error(format!(
33 "Account '{}' uses multiple currencies: {} and {}",
34 posting.account, existing, units.currency
35 )));
36 }
37 } else {
38 account_currencies
39 .insert(posting.account.clone(), units.currency.clone());
40 }
41 }
42 }
43 }
44 }
45
46 PluginOutput {
47 directives: input.directives,
48 errors,
49 }
50 }
51}