diff --git a/jaarg/src/argparse.rs b/jaarg/src/argparse.rs index 6b1ed6c..b398e52 100644 --- a/jaarg/src/argparse.rs +++ b/jaarg/src/argparse.rs @@ -140,7 +140,7 @@ impl Opts { // Ensure that all required arguments have been provided let mut required_flag_idx = 0; - for (i, option) in self.options.iter().enumerate() { + for (i, option) in self.iter().enumerate() { match option.r#type { OptType::Positional => if i >= state.positional_index && option.is_required() { error(program_name, ParseError::RequiredPositional(option.first_name())); @@ -192,7 +192,7 @@ impl Opts { let mut required_idx = 0; // Match a suitable option by name (ignoring the first flag character & skipping positional arguments) - let (name, option) = self.options.iter() + let (name, option) = self.iter() .filter(|opt| matches!(opt.r#type, OptType::Flag | OptType::Value)).find_map(|opt| { if let Some(name) = opt.match_name(option_str, 1) { Some((name, opt)) diff --git a/jaarg/src/help.rs b/jaarg/src/help.rs index 5c8e5a4..57b9275 100644 --- a/jaarg/src/help.rs +++ b/jaarg/src/help.rs @@ -23,7 +23,7 @@ impl core::fmt::Display for StandardShortUsageWriter<'_, ID> { write!(f, "Usage: {}", self.0.program_name)?; // Write option parameter arguments - for option in self.0.options.options.iter() + for option in self.0.options.iter() .filter(|o| matches!(o.r#type, OptType::Value | OptType::Flag)) { write!(f, " {}", if option.is_required() { '<' } else { '[' })?; match (option.first_short_name(), option.first_long_name()) { @@ -39,7 +39,7 @@ impl core::fmt::Display for StandardShortUsageWriter<'_, ID> { } // Write positional arguments - for option in self.0.options.options.iter() + for option in self.0.options.iter() .filter(|o| matches!(o.r#type, OptType::Positional)) { let name = option.first_name(); match option.is_required() { @@ -100,7 +100,7 @@ impl core::fmt::Display for StandardFullHelpWriter<'_, ID> { } // Write positional arguments - for option in self.0.options.options.iter() + for option in self.0.options.iter() .filter(|o| matches!(o.r#type, OptType::Positional)) { let name = option.first_name(); match option.is_required() { @@ -124,12 +124,12 @@ impl core::fmt::Display for StandardFullHelpWriter<'_, ID> { } // Determine the alignment width from the longest option parameter - let align_width = 2 + self.0.options.options.iter() + let align_width = 2 + self.0.options.iter() .map(|o| calculate_left_pad(o)).max().unwrap_or(0); // Write positional argument descriptions first = true; - for option in self.0.options.options.iter() + for option in self.0.options.iter() .filter(|o| matches!(o.r#type, OptType::Positional)) { if first { // Write separator and positional section header @@ -149,7 +149,7 @@ impl core::fmt::Display for StandardFullHelpWriter<'_, ID> { // Write option parameter argument descriptions first = true; - for option in self.0.options.options.iter() + for option in self.0.options.iter() .filter(|o| matches!(o.r#type, OptType::Flag | OptType::Value)) { if first { // Write separator and options section header diff --git a/jaarg/src/options.rs b/jaarg/src/options.rs index fa866cb..7ce8188 100644 --- a/jaarg/src/options.rs +++ b/jaarg/src/options.rs @@ -40,15 +40,35 @@ impl Opts { } } - /// Set the recognised flag/option characters. + /// Sets the recognised flag/option characters. + #[inline] pub const fn with_flag_chars(mut self, flag_chars: &'static str) -> Self { self.flag_chars = flag_chars; self } - /// Set the description of the program, available to help writers. + /// Sets the description of the program, available to help writers. + #[inline] pub const fn with_description(mut self, description: &'static str) -> Self { self.description = Some(description); self } + + /// Gets the first available help option if one exists. + pub const fn help_option(&self) -> Option<&'static Opt> { + let mut i = 0; + while i < self.options.len() { + if self.options[i].is_help() { + return Some(&self.options[i]); + } + i += 1; + } + None + } + + /// Gets an iterator over the parser's options. + #[inline] + pub fn iter(&self) -> core::slice::Iter<'static, Opt> { + self.options.iter() + } } diff --git a/jaarg/src/std.rs b/jaarg/src/std.rs index 8e39e10..28026f7 100644 --- a/jaarg/src/std.rs +++ b/jaarg/src/std.rs @@ -56,7 +56,7 @@ impl Opts { fn easy_error(&self, program_name: &str, err: ParseError) { eprintln!("{program_name}: {err}"); self.eprint_help::>(program_name); - if let Some(help_option) = self.options.iter().find(|o| o.is_help()) { + if let Some(help_option) = self.help_option() { eprintln!("Run '{program_name} {help}' to view all available options.", help = help_option.first_long_name().unwrap_or(help_option.first_name())); }