Generate financial statements from normalized accounting entries.
///|
test "readme example" {
let mappings = [AccountMapping::new("sales", "Revenue", IncomeStatement)]
let entries = [Entry::new("sales", "2026-Q2", 0, 1200)]
let report = generate(IncomeStatement, "2026-Q2", entries, mappings)
assert_eq(report.total, 1200)
assert_eq(report.line("Revenue"), Some(1200))
}moon check --target all --deny-warn
moon test --target all
moon run cmd/mainpub struct AccountDefinition {
code : String
name : String
class : AccountClass
normal_debit : Bool
} derive(Eq, Debug)fn AccountDefinition::new(code : String, name : String, class : AccountClass, normal_debit : Bool) -> AccountDefinitionpub struct AccountMapping {
account : String
line : String
kind : StatementKind
factor : Int
} derive(Eq, Debug)fn AccountMapping::new(account : String, line : String, kind : StatementKind, factor? : Int) -> AccountMappingpub struct Anomaly {
kind : AnomalyKind
account : String
period : String
amount : Int
detail : String
} derive(Eq, Debug)pub enum DatasetIssue {
InvalidEntry(Int, EntryValidation)
UnmappedEntry(Int, String)
DuplicateEntry(Int, Int)
} derive(Eq, Debug)fn ExchangeRate::new(from : String, to : String, numerator : Int, denominator : Int) -> ExchangeRatepub struct JournalEntry {
id : String
period : String
description : String
lines : Array[JournalLine]
} derive(Eq, Debug)pub struct Report {
kind : StatementKind
period : String
lines : Array[LineItem]
total : Int
} derive(Eq, Debug)pub struct TrialBalance {
lines : Array[TrialBalanceLine]
total_debit : Int
total_credit : Int
balanced : Bool
} derive(Eq, Debug)fn analyze_ratios(assets : Int, current_assets : Int, inventory : Int, liabilities : Int, revenue : Int, cost : Int, operating_expense : Int, net_income : Int) -> RatioSetfn build_report_pack(period : String, entries : Array[Entry], mappings : Array[AccountMapping]) -> ReportPackfn cash_flow(period : String, entries : Array[Entry], rules : Array[CashFlowRule]) -> Array[CashFlowLine]fn compare_reports(kind : StatementKind, current_period : String, prior_period : String, entries : Array[Entry], mappings : Array[AccountMapping]) -> ReportComparisonfn consolidate(period : String, entities : Array[Entity], mappings : Array[AccountMapping]) -> Reportfn consolidate_with_eliminations(period : String, entities : Array[Entity], mappings : Array[AccountMapping], rules : Array[EliminationRule]) -> Reportfn escape_html(value : String) -> Stringfn generate(kind : StatementKind, period : String, entries : Array[Entry], mappings : Array[AccountMapping], comparison? : String) -> Reportfn generate_by_dimension(kind : StatementKind, period : String, entries : Array[Entry], mappings : Array[AccountMapping]) -> Array[DimensionLine]fn generate_many(kind : StatementKind, periods : Array[String], entries : Array[Entry], mappings : Array[AccountMapping]) -> Array[Report]fn reconcile_cash(ledger : Array[CashRecord], statement : Array[CashRecord]) -> ReconciliationResultfn tax_summary(entries : Array[Entry], period : String, rules : Array[TaxRule], rate~ : Int) -> TaxSummaryfn validate_dataset(entries : Array[Entry], mappings : Array[AccountMapping]) -> Array[DatasetIssue]Install
Download zipGenerate financial statements from normalized accounting entries.