From 004f749c331e13e69953b5cf0fd0a2308fef191d Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Sat, 24 May 2025 01:01:03 +1000 Subject: [PATCH] Refactor steps_for_targets to accept Vec --- src/main.rs | 58 +++++++++++++++++++++++-------------- src/reporting/calculator.rs | 34 +++++++++++++--------- src/reporting/mod.rs | 7 +++-- 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1d03348..d169050 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,13 +21,10 @@ use libdrcr::db::DbConnection; use libdrcr::reporting::builders::register_dynamic_builders; use libdrcr::reporting::calculator::{steps_as_graphviz, steps_for_targets}; use libdrcr::reporting::generate_report; -use libdrcr::reporting::steps::{ - register_lookup_fns, AllTransactionsExceptEarningsToEquity, - AllTransactionsIncludingEarningsToEquity, CalculateIncomeTax, -}; +use libdrcr::reporting::steps::register_lookup_fns; use libdrcr::reporting::types::{ DateArgs, DateStartDateEndArgs, ReportingContext, ReportingProductId, ReportingProductKind, - ReportingStep, + VoidArgs, }; fn main() { @@ -46,13 +43,19 @@ fn main() { // Print Graphviz - let targets: Vec> = vec![ - Box::new(CalculateIncomeTax {}), - Box::new(AllTransactionsIncludingEarningsToEquity { - args: DateArgs { + let targets = vec![ + ReportingProductId { + name: "CalculateIncomeTax", + kind: ReportingProductKind::Transactions, + args: Box::new(VoidArgs {}), + }, + ReportingProductId { + name: "AllTransactionsIncludingEarningsToEquity", + kind: ReportingProductKind::BalancesAt, + args: Box::new(DateArgs { date: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(), - }, - }), + }), + }, ]; let (sorted_steps, dependencies) = steps_for_targets(targets, &context).unwrap(); @@ -61,15 +64,20 @@ fn main() { // Get income statement - let targets: Vec> = vec![ - Box::new(CalculateIncomeTax {}), - Box::new(AllTransactionsExceptEarningsToEquity { - product_kinds: &[ReportingProductKind::BalancesBetween], + let targets = vec![ + ReportingProductId { + name: "CalculateIncomeTax", + kind: ReportingProductKind::Transactions, + args: Box::new(VoidArgs {}), + }, + ReportingProductId { + name: "AllTransactionsExceptEarningsToEquity", + kind: ReportingProductKind::BalancesBetween, args: Box::new(DateStartDateEndArgs { date_start: NaiveDate::from_ymd_opt(2024, 7, 1).unwrap(), date_end: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(), }), - }), + }, ]; let products = generate_report(targets, &context).unwrap(); @@ -89,13 +97,19 @@ fn main() { // Get balance sheet - let targets: Vec> = vec![ - Box::new(CalculateIncomeTax {}), - Box::new(AllTransactionsIncludingEarningsToEquity { - args: DateArgs { + let targets = vec![ + ReportingProductId { + name: "CalculateIncomeTax", + kind: ReportingProductKind::Transactions, + args: Box::new(VoidArgs {}), + }, + ReportingProductId { + name: "AllTransactionsIncludingEarningsToEquity", + kind: ReportingProductKind::BalancesAt, + args: Box::new(DateArgs { date: NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(), - }, - }), + }), + }, ]; let products = generate_report(targets, &context).unwrap(); diff --git a/src/reporting/calculator.rs b/src/reporting/calculator.rs index 65fdb2c..35de398 100644 --- a/src/reporting/calculator.rs +++ b/src/reporting/calculator.rs @@ -207,33 +207,41 @@ fn would_be_ready_to_execute( true } -/// Recursively resolve the dependencies of the target [ReportingStep]s and return a sorted [Vec] of [ReportingStep]s +/// Recursively resolve the dependencies of the target [ReportingProductId]s and return a sorted [Vec] of [ReportingStep]s pub fn steps_for_targets( - targets: Vec>, + targets: Vec, context: &ReportingContext, ) -> Result<(Vec>, ReportingGraphDependencies), ReportingCalculationError> { let mut steps: Vec> = Vec::new(); let mut dependencies = ReportingGraphDependencies { vec: Vec::new() }; - // Initialise targets - for target in targets { - steps.push(target); - let target = steps.last().unwrap(); - for dependency in target.requires(&context) { - dependencies.add_dependency(target.id(), dependency); + // Process initial targets + for target in targets.iter() { + if !steps.iter().any(|s| { + s.id().name == target.name + && s.id().args == target.args + && s.id().product_kinds.contains(&target.kind) + }) { + // No current step generates the product - try to lookup or build + if let Some(new_step) = build_step_for_product(&target, &steps, &dependencies, context) + { + steps.push(new_step); + let new_step = steps.last().unwrap(); + for dependency in new_step.requires(&context) { + dependencies.add_dependency(new_step.id(), dependency); + } + new_step.init_graph(&steps, &mut dependencies, &context); + } } - target - .as_ref() - .init_graph(&steps, &mut dependencies, &context); } - // Call after_init_graph on targets + // Call after_init_graph for step in steps.iter() { step.as_ref() .after_init_graph(&steps, &mut dependencies, &context); } - // Process dependencies + // Recursively process dependencies loop { let mut new_steps = Vec::new(); diff --git a/src/reporting/mod.rs b/src/reporting/mod.rs index 411a8ef..aabe51c 100644 --- a/src/reporting/mod.rs +++ b/src/reporting/mod.rs @@ -18,7 +18,7 @@ use calculator::{steps_for_targets, ReportingCalculationError}; use executor::{execute_steps, ReportingExecutionError}; -use types::{ReportingContext, ReportingProducts, ReportingStep}; +use types::{ReportingContext, ReportingProductId, ReportingProducts}; pub mod builders; pub mod calculator; @@ -44,8 +44,11 @@ impl From for ReportingError { } } +/// Calculate the steps required to generate the requested [ReportingProductId]s and then execute them +/// +/// Helper function to call [steps_for_targets] followed by [execute_steps]. pub fn generate_report( - targets: Vec>, + targets: Vec, context: &ReportingContext, ) -> Result { // Solve dependencies