From bcce61c8093d75212e6c5e365e3326781a0953c2 Mon Sep 17 00:00:00 2001 From: Mitchell M Date: Thu, 4 Jun 2026 19:21:56 -0500 Subject: [PATCH] add support for quanity --- src/main.rs | 93 +++++++++++++++++++++++++++++++++++++---------------- src/pdf.rs | 0 2 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 src/pdf.rs diff --git a/src/main.rs b/src/main.rs index 0ab5cd4..8ade7fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +pub mod pdf; + use clap::{Parser, ValueEnum}; use colored::*; @@ -45,6 +47,10 @@ struct Args { /// Control terminal color output #[arg(long, default_value = "auto")] color: ColorChoice, + + /// Number of casts to make simultaneously + #[arg(short = 'n', long, default_value_t = 1)] + quantity: u32, } fn main() { @@ -57,7 +63,7 @@ fn main() { ColorChoice::Auto => {} // Respects standard stream capabilities (default) } - // Determine density and target wet weight + // Determine density and target wet weight for a SINGLE cast let density = args.density.or_else(|| { if (args.concentration - DEFAULT_CONCENTRATION).abs() < f64::EPSILON { Some(DEFAULT_DENSITY) @@ -65,9 +71,11 @@ fn main() { None } }); - let target_wet_weight = density.map(|d| (args.volume / 1000.0) * d); - let (plaster_nominal, water_nominal) = match target_wet_weight { + let single_wet_weight = density.map(|d| (args.volume / 1000.0) * d); + let total_wet_weight = single_wet_weight.map(|w| w * args.quantity as f64); + + let (plaster_total, water_total) = match total_wet_weight { Some(wet_weight) => { let plaster = wet_weight / (1.0 + (args.concentration / PERCENT)); let water = plaster * (args.concentration / PERCENT); @@ -79,37 +87,56 @@ fn main() { // Output Header println!("--- Plaster Calculation Parameters ---"); println!( - "Volume: {}ml", + "Volume (per cast): {}ml", format!("{}", args.volume).color(COLOR_PARAM).bold() ); println!( - "Concentration: {}g water per 100g plaster", + "Quantity: {}", + format!("{}", args.quantity).color(COLOR_PARAM).bold() + ); + println!( + "Concentration: {}g water per 100g plaster", format!("{}", args.concentration).color(COLOR_PARAM).bold() ); let density_str = density.map_or("Not provided/calculated".to_string(), |d| { format!("{}g/L", format!("{}", d).color(COLOR_PARAM).bold()) }); - println!("Density: {}", density_str); + println!("Density: {}", density_str); println!("--------------------------------------"); // Output Mixing Amounts and Target Weights - if let (Some(p_nom), Some(w_nom)) = (plaster_nominal, water_nominal) { - let p_slack = p_nom * (1.0 + SLACK); - let w_slack = w_nom * (1.0 + SLACK); - let dry_weight = p_nom * DRY_WEIGHT_MULTIPLIER; + if let (Some(p_tot), Some(w_tot)) = (plaster_total, water_total) { + let p_slack = p_tot * (1.0 + SLACK); + let w_slack = w_tot * (1.0 + SLACK); + + let single_plaster = p_tot / args.quantity as f64; + let single_dry_weight = single_plaster * DRY_WEIGHT_MULTIPLIER; + let total_dry_weight = single_dry_weight * args.quantity as f64; + + if args.quantity > 1 { + println!("Combined Mixing Amounts (for {} casts):", args.quantity); + println!(" Nominal Total:"); + } else { + println!("Mixing Amounts:"); + println!(" Nominal:"); + } - println!("Mixing Amounts:"); - println!(" Nominal:"); println!( " Plaster: {}g", - format!("{:.1}", p_nom).color(COLOR_PLASTER) + format!("{:.1}", p_tot).color(COLOR_PLASTER) ); println!( " Water: {}g", - format!("{:.1}", w_nom).color(COLOR_WATER) + format!("{:.1}", w_tot).color(COLOR_WATER) ); - println!(" {:2}% Slack:", SLACK * PERCENT); + + if args.quantity > 1 { + println!(" {:2}% Slack Total:", SLACK * PERCENT); + } else { + println!(" {:2}% Slack:", SLACK * PERCENT); + } + println!( " Plaster: {}g", format!("{:.1}", p_slack).color(COLOR_PLASTER).bold() @@ -120,19 +147,31 @@ fn main() { ); println!("\nTarget Weights:"); - println!( - " Wet Cast: {}g", - format!("{:.1}", target_wet_weight.unwrap()) - .color(COLOR_TARGET) - .bold() - ); - println!( - " Dry Cast: {}g", - format!("{:.1}", dry_weight).color(COLOR_TARGET).bold() - ); + if args.quantity > 1 { + println!(" Individual Cast:"); + } + println!( + " Wet Cast: {}g", + format!("{:.1}", single_wet_weight.unwrap()).color(COLOR_TARGET).bold() + ); + println!( + " Dry Cast: {}g", + format!("{:.1}", single_dry_weight).color(COLOR_TARGET).bold() + ); + if args.quantity > 1 { + println!(" Total Batch:"); + println!( + " Wet Cast: {}g", + format!("{:.1}", total_wet_weight.unwrap()).color(COLOR_TARGET) + ); + println!( + " Dry Cast: {}g", + format!("{:.1}", total_dry_weight).color(COLOR_TARGET) + ); + } } else { - println!("{}", - "Target weights and mixing amounts cannot be calculated. Please specify a density with `-d` for any non-70 concentration.".red() + println!("{}", + "Target weights and mixing amounts cannot be calculated. Please specify a density with `-d` for any non-70 concentration.".red() ); } } diff --git a/src/pdf.rs b/src/pdf.rs new file mode 100644 index 0000000..e69de29