diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..9665dec --- /dev/null +++ b/src/args.rs @@ -0,0 +1,172 @@ +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, + + /// 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, + ); + } +} diff --git a/src/main.rs b/src/main.rs index 5e0b998..83f0047 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,19 @@ +pub mod args; pub mod layers; pub mod mushroom; pub mod render; pub mod translate; -use self::mushroom::Mushroom; -use clap::Parser; use std::fs::OpenOptions; extern crate approx; -pub use serde_derive::{Deserialize, Serialize}; +use clap::Parser; fn main() { - let args = Args::parse(); + let args = args::Args::parse(); // Define the mushroom. - let mushroom = mushroom_from_args(&args); + let mushroom = args.mushroom_from_args(); // Render the mushroom. // let mesh = render::cylinder(mushroom.stalk_h, mushroom.stalk_d, 128); @@ -32,171 +31,3 @@ fn main() { println!("Generated from: {:?}", mushroom); } - -#[derive(Parser, Debug, Clone)] -#[command(version, about, long_about = None)] -struct Args { - /// File to save too. - #[arg(long, default_value = "mesh.stl")] - output: String, - - /// Height of total mushroom in millimeters. - #[arg(long, default_value_t = 100)] - height: u32, - - /// Stalk height in millimeters. Zero for default. - #[arg(long, default_value_t = 0)] - stalk_h: u32, - - /// Stalk diameter in millimeters. Zero for default. - #[arg(long, default_value_t = 0)] - stalk_d: u32, - - /// Cap height in millimeters. Zero for default. - #[arg(long, default_value_t = 0)] - cap_h: u32, - - /// Stalk diameter in millimeters. Zero for default. - #[arg(long, default_value_t = 0)] - cap_d: u32, - - /// Shape of the cap. - #[arg(long, default_value_t, value_enum)] - cap_style: mushroom::CapStyle, -} - -fn mushroom_from_args(args: &Args) -> Mushroom { - // Default values are all based on height. - let stalk_h: f32 = if args.stalk_h != 0 { - args.stalk_h as f32 - } else { - if args.cap_h != 0 { - (args.height - args.cap_h) as f32 - } else { - args.height as f32 * 0.66 - } - }; - let stalk_r: f32 = if args.stalk_d != 0 { - args.stalk_d as f32 - } else { - args.height as f32 / 10. - } / 2.0; // computer the diamter, and convert to radius. - let cap_h: f32 = if args.cap_h != 0 { - args.cap_h as f32 - } else { - args.height as f32 - stalk_h - }; - let cap_r: f32 = if args.cap_d != 0 { - args.cap_d as f32 - } else { - args.height as f32 - } / 2.0; // computer the diamter, and convert to radius. - - let cap_style = args.cap_style.clone(); - - 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 = mushroom_from_args(&parsed_args); - assert_eq!( - result, - 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, - ); - } -}