1 unstable release
0.2.2 | Feb 1, 2025 |
---|
#1 in #tktax
129 downloads per month
Used in tktax
255KB
3K
SLoC
tktax-budgeting
tktax-budgeting is a Rust library in the tktax ecosystem providing structures and traits for budget management and transaction category comparisons. It enables users to:
- Define budgets on monthly, quarterly, or annual time horizons.
- Compare actual expenditures or credits to budgeted amounts per category.
- Employ strongly-typed domain models with robust error handling (no stringly-typed errors).
Features
-
Budget<TxCat>
- Stores monthly category amounts and default allocations.
- Built using
derive_builder
, allowing for flexible initialization. - Methods for dynamically setting or removing category budgets without re-instantiation.
-
BudgetComparison<TxCat>
- Summarizes per-category actual vs. budgeted values, including a variance measurement.
-
Budgeting<TxCat>
Trait- Facilitates budget-to-actual comparisons for a domain
Account
. - Offers both per-month and aggregate-based comparison methods.
- Facilitates budget-to-actual comparisons for a domain
-
Time Period Abstractions
BudgetTimePeriod
enumerates supported intervals (Monthly, Quarterly, Annual).
-
Error Handling
BudgetError
covers domain-specific error conditions without resorting to textual messages.
Usage
Add the following to your Cargo.toml
:
[dependencies]
tktax-budgeting = "0.1.0"
Example
use tktax_budgeting::{
BudgetBuilder, Budget, Budgeting, BudgetTimePeriod,
BudgetComparison, BudgetError,
};
use tktax_account::Account;
use tktax_money::MonetaryAmount;
use tktax_transaction_category::TransactionCategory;
use std::collections::HashMap;
// Custom transaction category for illustration:
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
enum MyCategory {
Dining,
Groceries,
Rent,
}
// Implement the TransactionCategory trait:
impl TransactionCategory for MyCategory {}
// Construct a budget:
let mut monthly_budgets = HashMap::new();
monthly_budgets.insert(MyCategory::Dining, MonetaryAmount::from(200));
monthly_budgets.insert(MyCategory::Groceries, MonetaryAmount::from(300));
monthly_budgets.insert(MyCategory::Rent, MonetaryAmount::from(800));
let budget = BudgetBuilder::<MyCategory>::default()
.monthly_category_budgets(monthly_budgets)
.default_monthly_budget(MonetaryAmount::from(50))
.time_period(BudgetTimePeriod::Monthly)
.build()
.map_err(|_| BudgetError::IncompleteBuilder)?;
// Suppose we already have an Account populated with transactions:
let my_account = Account::empty(); // your domain logic populates it
// We also have a category map, or a function to map transactions to MyCategory:
let category_map = /* your domain CategoryMap<MyCategory> */;
// Compare actual amounts to budget:
let comps = my_account.compare_actual_to_budget_monthly(&budget, &category_map);
for comparison in comps {
println!(
"Category: {:?}, Budgeted: {}, Actual: {}, Variance: {}",
comparison.category(),
comparison.budgeted(),
comparison.actual(),
comparison.variance()
);
}
Testing
The library contains a suite of unit tests demonstrating the usage patterns:
- Verifying the
Budget
builder defaults and field assignments. - Checking dynamic category budget addition and removal.
- Confirming correct computation of variances.
To run tests:
cargo test
Contributing
Contributions or issues can be reported at the project repository.
License
This project is licensed under the MIT license.
Dependencies
~29–39MB
~674K SLoC