use std::{fs::File, io::BufWriter, path::PathBuf}; use clap::{Parser, Subcommand}; use coster_rs::CreateProductInputs; #[derive(Parser)] #[command(name = "coster-rs")] #[command(author = "Pivato M. ")] #[command(version = "0.0.1")] #[command(about = "Simple, fast, efficient costing tool", long_about = None)] struct Cli { #[clap(subcommand)] command: Commands, } #[derive(Subcommand)] enum Commands { /// Moves money between accounts and departments, using the given rules and lines MoveMoney { #[arg(short = 'r', long, value_name = "FILE")] rules: PathBuf, #[arg(short = 'l', long, value_name = "FILE")] lines: PathBuf, #[arg(short = 'a', long, value_name = "FILE")] accounts: PathBuf, #[arg(short = 'c', long, value_name = "FILE")] cost_centres: PathBuf, #[arg(short, long, value_name = "FILE")] output: Option, #[arg(short, long)] use_numeric_accounts: bool, #[arg(short, long)] flush_pass: bool, }, /// Allocates servicing department amounts to operating departments AllocateOverheads { #[arg(short, long, value_name = "FILE")] lines: PathBuf, #[arg(short, long, value_name = "FILE")] accounts: PathBuf, #[arg(short = 's', long, value_name = "FILE")] allocation_statistics: PathBuf, #[arg(short, long, value_name = "FILE")] areas: PathBuf, #[arg(short, long, value_name = "FILE")] cost_centres: PathBuf, #[arg(short, long)] use_numeric_accounts: bool, #[arg(long, default_value = "E")] account_type: String, #[arg(short, long)] exclude_negative_allocation_statistics: bool, #[arg(short = 'f', long)] show_from: bool, #[arg(short, long, default_value = "0.00000000000000001")] zero_threshold: f64, #[arg(short, long, value_name = "FILE", default_value = "alloc_output.csv")] output: PathBuf, #[arg(short, long)] msgpack_serialisation: bool, }, CreateProducts { #[arg(short, long, value_name = "FILE")] definitions: PathBuf, #[arg(short, long, value_name = "FILE")] encounters: PathBuf, #[arg(short, long, value_name = "FILE")] services: PathBuf, #[arg(short, long, value_name = "FILE")] transfers: PathBuf, #[arg(short, long, value_name = "FILE")] procedures: PathBuf, #[arg(short, long, value_name = "FILE")] diagnoses: PathBuf, #[arg(short, long, value_name = "FILE")] output: PathBuf, }, } fn main() -> anyhow::Result<()> { let cli = Cli::parse(); match cli.command { Commands::MoveMoney { rules, lines, accounts, cost_centres, output, use_numeric_accounts, flush_pass, } => coster_rs::move_money( &mut csv::Reader::from_path(rules)?, &mut csv::Reader::from_path(lines)?, &mut csv::Reader::from_path(accounts)?, &mut csv::Reader::from_path(cost_centres)?, &mut csv::Writer::from_path(output.unwrap_or(PathBuf::from("output.csv")))?, use_numeric_accounts, flush_pass, ), Commands::AllocateOverheads { lines, accounts, allocation_statistics, areas, cost_centres, use_numeric_accounts, account_type, exclude_negative_allocation_statistics, show_from, zero_threshold, output, msgpack_serialisation, } => { if msgpack_serialisation { let mut file = BufWriter::new(File::create(output)?); coster_rs::reciprocal_allocation( &mut csv::Reader::from_path(lines)?, &mut csv::Reader::from_path(accounts)?, &mut csv::Reader::from_path(allocation_statistics)?, &mut csv::Reader::from_path(areas)?, &mut csv::Reader::from_path(cost_centres)?, &mut rmp_serde::Serializer::new(&mut file), use_numeric_accounts, exclude_negative_allocation_statistics, true, account_type, show_from, zero_threshold, ) } else { coster_rs::reciprocal_allocation( &mut csv::Reader::from_path(lines)?, &mut csv::Reader::from_path(accounts)?, &mut csv::Reader::from_path(allocation_statistics)?, &mut csv::Reader::from_path(areas)?, &mut csv::Reader::from_path(cost_centres)?, &mut csv::Writer::from_path(output)?, use_numeric_accounts, exclude_negative_allocation_statistics, true, account_type, show_from, zero_threshold, ) } } Commands::CreateProducts { definitions, encounters, services, transfers, procedures, diagnoses, output, } => coster_rs::create_products( &mut csv::Reader::from_path(definitions)?, CreateProductInputs { encounters: csv::Reader::from_path(encounters)?, services: csv::Reader::from_path(services)?, transfers: csv::Reader::from_path(transfers)?, procedures: csv::Reader::from_path(procedures)?, diagnoses: csv::Reader::from_path(diagnoses)?, }, &mut csv::Writer::from_path(output)?, 1000000, ), } }