use crate::mushroom; use clap::Parser; #[derive(Parser, Debug, Clone)] #[command(version, about, long_about = None)] pub struct Args { /// File to save too. #[arg(long, default_value = "mesh.stl")] pub output: String, /// Shape of the cap. #[arg(long, default_value_t = false)] pub run_server: bool, /// Height of total mushroom in millimeters. #[arg(long, default_value_t = 100)] pub height: u32, /// Stalk height in millimeters. Zero for default. #[arg(long, default_value_t = 0)] pub stalk_h: u32, /// Stalk diameter in millimeters. Zero for default. #[arg(long, default_value_t = 0)] pub stalk_d: u32, /// Cap height in millimeters. Zero for default. #[arg(long, default_value_t = 0)] pub cap_h: u32, /// Stalk diameter in millimeters. Zero for default. #[arg(long, default_value_t = 0)] pub cap_d: u32, /// Shape of the cap. #[arg(long, default_value_t, value_enum)] pub cap_style: mushroom::CapStyle, } impl Args { pub fn mushroom_from_args(&self) -> mushroom::Mushroom { // Default values are all based on height. let stalk_h: f32 = if self.stalk_h != 0 { self.stalk_h as f32 } else { if self.cap_h != 0 { (self.height - self.cap_h) as f32 } else { self.height as f32 * 0.66 } }; let stalk_r: f32 = if self.stalk_d != 0 { self.stalk_d as f32 } else { self.height as f32 / 10. } / 2.0; // computer the diamter, and convert to radius. let cap_h: f32 = if self.cap_h != 0 { self.cap_h as f32 } else { self.height as f32 - stalk_h }; let cap_r: f32 = if self.cap_d != 0 { self.cap_d as f32 } else { self.height as f32 } / 2.0; // computer the diamter, and convert to radius. let cap_style = self.cap_style.clone(); mushroom::Mushroom { stalk_h, stalk_r, cap_h, cap_r, cap_style, } } } #[cfg(test)] mod tests { use super::*; use std::ffi::OsString; fn validate_mushroom_from_args( string_args: I, stalk_h: f32, stalk_r: f32, cap_h: f32, cap_r: f32, cap_style: mushroom::CapStyle, ) where I: IntoIterator, T: Into + Clone, { let parsed_args = Args::parse_from(string_args); let result = parsed_args.mushroom_from_args(); assert_eq!( result, mushroom::Mushroom { stalk_h, stalk_r, cap_h, cap_r, cap_style, } ); } #[test] fn defaults() { validate_mushroom_from_args(["prog"], 66.0, 5.0, 34.0, 50.0, mushroom::CapStyle::Dome); } #[test] fn height_only() { validate_mushroom_from_args( ["prog", "--height", "200"], 132.0, 10.0, 68.0, 100.0, mushroom::CapStyle::Dome, ); } #[test] fn height_stalk_h() { validate_mushroom_from_args( ["prog", "--height", "200", "--stalk-h", "20"], 20.0, 10.0, 180.0, 100.0, mushroom::CapStyle::Dome, ); } #[test] fn height_cap_h() { validate_mushroom_from_args( ["prog", "--height", "200", "--cap-h", "20"], 180.0, 10.0, 20.0, 100.0, mushroom::CapStyle::Dome, ); } #[test] fn all() { validate_mushroom_from_args( [ "prog", "--height", "10", "--stalk-h", "20", "--stalk-d", "30", "--cap-h", "40", "--cap-d", "50", "--cap-style", "pointed", ], 20.0, 15.0, 40.0, 25.0, mushroom::CapStyle::Pointed, ); } }