Skip to content

Commit 3147202

Browse files
committed
[update] documentation
1 parent 090dbe8 commit 3147202

1 file changed

Lines changed: 141 additions & 19 deletions

File tree

  • crates/lambda-rs-args/src

crates/lambda-rs-args/src/lib.rs

Lines changed: 141 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -427,11 +427,35 @@ impl ArgumentParser {
427427
out
428428
}
429429

430-
/// New non-panicking parser. Prefer this over `compile`.
430+
/// Parses a slice of tokens into typed arguments.
431+
///
432+
/// # Arguments
433+
/// - `args`: Token vector (typically `std::env::args().collect()`). The first
434+
/// token is treated as the executable name and is ignored for parsing.
435+
///
436+
/// # Returns
437+
/// Returns a `ParsedArgs` containing declared options/flags/positionals (with
438+
/// defaults applied) and an optional parsed subcommand.
439+
///
440+
/// # Errors
441+
/// Returns `ArgsError` when:
442+
/// - `--help` / `-h` is present (`ArgsError::HelpRequested`).
443+
/// - An unknown argument is encountered in strict mode.
444+
/// - A value is missing for a value-taking argument.
445+
/// - A value fails type parsing.
446+
/// - A required argument is not provided.
447+
/// - Mutually exclusive or requires relationships are violated.
448+
///
449+
/// - Aliases are resolved during parsing; lookups on `ParsedArgs` use the
450+
/// declared argument name (canonical form), not an alias.
451+
/// - Combined short flags like `-vvv` are supported only for `Count` and
452+
/// `Boolean` arguments.
431453
pub fn parse(mut self, args: &[String]) -> Result<ParsedArgs, ArgsError> {
432454
// Errors are returned, not panicked.
433455
let mut collecting_values = false;
434456
let mut last_key: Option<String> = None;
457+
// Cursor into `self.positionals` so assigning `--` values is O(p) total,
458+
// rather than O(p^2) across p positionals.
435459
let mut next_positional_idx: usize = 0;
436460

437461
let mut parsed_arguments = vec![];
@@ -458,11 +482,10 @@ impl ArgumentParser {
458482
}
459483
let sub = self.subcommands.remove(t).unwrap();
460484
let sub_parsed = sub.parse(&argv)?;
461-
return Ok(ParsedArgs {
462-
values: vec![],
463-
index_by_name: HashMap::new(),
464-
subcommand: Some((t.to_string(), Box::new(sub_parsed))),
465-
});
485+
return Ok(ParsedArgs::new(
486+
vec![],
487+
Some((t.to_string(), Box::new(sub_parsed))),
488+
));
466489
}
467490
}
468491
while let Some(token) = iter.next() {
@@ -477,11 +500,10 @@ impl ArgumentParser {
477500
}
478501
let sub = self.subcommands.remove(arg_token).unwrap();
479502
let sub_parsed = sub.parse(&argv2)?;
480-
return Ok(ParsedArgs {
481-
values: vec![],
482-
index_by_name: HashMap::new(),
483-
subcommand: Some((arg_token.to_string(), Box::new(sub_parsed))),
484-
});
503+
return Ok(ParsedArgs::new(
504+
vec![],
505+
Some((arg_token.to_string(), Box::new(sub_parsed))),
506+
));
485507
}
486508

487509
if arg_token == "--help" || arg_token == "-h" {
@@ -764,6 +786,16 @@ impl ArgumentParser {
764786
}
765787

766788
/// Backwards‑compatible panicking API. Prefer `parse` for non‑panicking use.
789+
///
790+
/// # Arguments
791+
/// - `args`: Token vector (typically `std::env::args().collect()`). The first
792+
/// token is treated as the executable name and is ignored for parsing.
793+
///
794+
/// # Returns
795+
/// Returns the raw `(name, value)` vector of parsed arguments.
796+
///
797+
/// # Panics
798+
/// Panics with a formatted `ArgsError` string if parsing fails.
767799
pub fn compile(self, args: &[String]) -> Vec<ParsedArgument> {
768800
match self.parse(args) {
769801
Ok(parsed) => parsed.into_vec(),
@@ -884,15 +916,31 @@ impl fmt::Display for ArgsError {
884916

885917
impl std::error::Error for ArgsError {}
886918

887-
/// Parsed arguments with typed getters and subcommand support.
919+
/// Parsed arguments with typed getters and optional subcommand support.
920+
///
921+
/// `ParsedArgs` is produced by `ArgumentParser::parse`. Lookups are optimized
922+
/// for runtime usage (O(1) by name) by building an index when parsing
923+
/// completes.
888924
#[derive(Debug, Clone)]
889925
pub struct ParsedArgs {
890926
values: Vec<ParsedArgument>,
927+
/// Lookup table from argument name to its index in `values`.
928+
///
929+
/// This allows `has()` and `get_*()` calls to be O(1) instead of scanning
930+
/// the full vector on every lookup.
891931
index_by_name: HashMap<String, usize>,
892932
subcommand: Option<(String, Box<ParsedArgs>)>,
893933
}
894934

895935
impl ParsedArgs {
936+
/// Creates a `ParsedArgs` from raw parsed values.
937+
///
938+
/// # Arguments
939+
/// - `values`: Parsed arguments, indexed by the parser's internal ordering.
940+
/// - `subcommand`: Optional subcommand parse result.
941+
///
942+
/// # Returns
943+
/// Returns a `ParsedArgs` with an O(1) name index for lookups.
896944
fn new(
897945
values: Vec<ParsedArgument>,
898946
subcommand: Option<(String, Box<ParsedArgs>)>,
@@ -910,20 +958,41 @@ impl ParsedArgs {
910958
}
911959
}
912960

913-
/// Convert into the raw underlying `(name, value)` vector.
961+
/// Converts into the raw underlying `(name, value)` vector.
962+
///
963+
/// # Returns
964+
/// Returns the internal parsed argument vector in parser order.
914965
pub fn into_vec(self) -> Vec<ParsedArgument> {
915966
self.values
916967
}
917968

918-
/// True if the named argument is present (and not `None`).
969+
/// Returns `true` if the named argument is present (and not `None`).
970+
///
971+
/// # Arguments
972+
/// - `name`: The declared argument name (for example, `"--port"` or
973+
/// `"input"`).
974+
///
975+
/// # Returns
976+
/// Returns `true` when the argument is present and was not parsed as
977+
/// `ArgumentValue::None`.
978+
///
979+
/// Aliases like `"-p"` are not resolved at lookup time. Use the canonical
980+
/// argument name.
919981
pub fn has(&self, name: &str) -> bool {
920982
let Some(idx) = self.index_by_name.get(name) else {
921983
return false;
922984
};
923985
return !matches!(self.values[*idx].value, ArgumentValue::None);
924986
}
925987

926-
/// Get a `String` value by name, if present and typed as string.
988+
/// Returns a `String` value by name, if present and typed as string.
989+
///
990+
/// # Arguments
991+
/// - `name`: The declared argument name (for example, `"--title"`).
992+
///
993+
/// # Returns
994+
/// Returns `Some(String)` when the argument exists and is a string, otherwise
995+
/// returns `None`.
927996
pub fn get_string(&self, name: &str) -> Option<String> {
928997
let idx = self.index_by_name.get(name)?;
929998
match &self.values[*idx].value {
@@ -932,7 +1001,14 @@ impl ParsedArgs {
9321001
}
9331002
}
9341003

935-
/// Get an `i64` value by name, if present and typed as integer.
1004+
/// Returns an `i64` value by name, if present and typed as integer.
1005+
///
1006+
/// # Arguments
1007+
/// - `name`: The declared argument name (for example, `"--count"`).
1008+
///
1009+
/// # Returns
1010+
/// Returns `Some(i64)` when the argument exists and is an integer, otherwise
1011+
/// returns `None`.
9361012
pub fn get_i64(&self, name: &str) -> Option<i64> {
9371013
let idx = self.index_by_name.get(name)?;
9381014
match &self.values[*idx].value {
@@ -941,7 +1017,14 @@ impl ParsedArgs {
9411017
}
9421018
}
9431019

944-
/// Get an `f32` value by name, if present and typed as float.
1020+
/// Returns an `f32` value by name, if present and typed as float.
1021+
///
1022+
/// # Arguments
1023+
/// - `name`: The declared argument name.
1024+
///
1025+
/// # Returns
1026+
/// Returns `Some(f32)` when the argument exists and is a float, otherwise
1027+
/// returns `None`.
9451028
pub fn get_f32(&self, name: &str) -> Option<f32> {
9461029
let idx = self.index_by_name.get(name)?;
9471030
match &self.values[*idx].value {
@@ -950,7 +1033,14 @@ impl ParsedArgs {
9501033
}
9511034
}
9521035

953-
/// Get an `f64` value by name, if present and typed as double.
1036+
/// Returns an `f64` value by name, if present and typed as double.
1037+
///
1038+
/// # Arguments
1039+
/// - `name`: The declared argument name.
1040+
///
1041+
/// # Returns
1042+
/// Returns `Some(f64)` when the argument exists and is a double, otherwise
1043+
/// returns `None`.
9541044
pub fn get_f64(&self, name: &str) -> Option<f64> {
9551045
let idx = self.index_by_name.get(name)?;
9561046
match &self.values[*idx].value {
@@ -959,7 +1049,14 @@ impl ParsedArgs {
9591049
}
9601050
}
9611051

962-
/// Get a `bool` value by name, if present and typed as boolean.
1052+
/// Returns a `bool` value by name, if present and typed as boolean.
1053+
///
1054+
/// # Arguments
1055+
/// - `name`: The declared argument name (for example, `"--verbose"`).
1056+
///
1057+
/// # Returns
1058+
/// Returns `Some(bool)` when the argument exists and is a boolean, otherwise
1059+
/// returns `None`.
9631060
pub fn get_bool(&self, name: &str) -> Option<bool> {
9641061
let idx = self.index_by_name.get(name)?;
9651062
match &self.values[*idx].value {
@@ -968,6 +1065,14 @@ impl ParsedArgs {
9681065
}
9691066
}
9701067

1068+
/// Returns a count value by name, if present and typed as integer.
1069+
///
1070+
/// # Arguments
1071+
/// - `name`: The declared argument name (for example, `"-v"`).
1072+
///
1073+
/// # Returns
1074+
/// Returns `Some(i64)` when the argument exists and is an integer, otherwise
1075+
/// returns `None`.
9711076
pub fn get_count(&self, name: &str) -> Option<i64> {
9721077
let idx = self.index_by_name.get(name)?;
9731078
match &self.values[*idx].value {
@@ -976,6 +1081,10 @@ impl ParsedArgs {
9761081
}
9771082
}
9781083

1084+
/// Returns the parsed subcommand, if present.
1085+
///
1086+
/// # Returns
1087+
/// Returns `Some((name, args))` when a subcommand was matched during parse.
9791088
pub fn subcommand(&self) -> Option<(&str, &ParsedArgs)> {
9801089
self
9811090
.subcommand
@@ -1294,12 +1403,25 @@ impl ArgumentParser {
12941403
None
12951404
}
12961405

1406+
/// Assigns the next positional argument in declaration order.
1407+
///
1408+
/// # Arguments
1409+
/// - `out`: Output argument storage indexed by the parser's internal order.
1410+
/// - `value`: Token to assign to the next positional argument.
1411+
/// - `next_positional_idx`: Cursor into `self.positionals` tracking the next
1412+
/// candidate positional to assign.
1413+
///
1414+
/// # Errors
1415+
/// Returns `ArgsError::InvalidValue` when no remaining positionals exist
1416+
/// (extra positional arguments).
12971417
fn assign_next_positional(
12981418
&mut self,
12991419
out: &mut [ParsedArgument],
13001420
value: &str,
13011421
next_positional_idx: &mut usize,
13021422
) -> Result<(), ArgsError> {
1423+
// Assign the next positional in declaration order. `next_positional_idx`
1424+
// ensures we never rescan previously-considered positionals.
13031425
while *next_positional_idx < self.positionals.len() {
13041426
let pname = &self.positionals[*next_positional_idx];
13051427
*next_positional_idx += 1;

0 commit comments

Comments
 (0)