Skip to main content

rustledger_plugin/native/plugins/
one_commodity.rs

1//! Enforce single commodity per account.
2
3use crate::types::{DirectiveData, PluginError, PluginInput, PluginOutput};
4
5use super::super::NativePlugin;
6
7/// Plugin that enforces single commodity per account.
8pub 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        // Track currencies used per account
23        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}