Expand description
Command-line and REPL parsing
This module provides comprehensive parsing functionality for both traditional command-line interfaces (CLI) and interactive REPL mode.
§Module Structure
The parser module consists of three main components:
type_parser: Type conversion functions (string → typed values)cli_parser: CLI argument parser (Unix-style options)repl_parser: REPL line parser (interactive mode)
§Architecture
┌─────────────────────────────────────────┐
│ User Input │
│ "process file.txt --verbose" │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ ReplParser (REPL mode) │
│ - Tokenize line │
│ - Resolve command name via Registry │
│ - Delegate to CliParser │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ CliParser (CLI mode) │
│ - Parse positional arguments │
│ - Parse options (-v, --verbose) │
│ - Apply defaults │
│ - Use TypeParser for conversion │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ TypeParser │
│ - Convert strings to typed values │
│ - Validate type constraints │
└──────────────┬──────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ HashMap<String, String> │
│ {"input": "file.txt", │
│ "verbose": "true"} │
└─────────────────────────────────────────┘§Design Principles
§1. Separation of Concerns
Each parser has a specific responsibility:
- TypeParser: Handles type conversion only
- CliParser: Handles CLI syntax (options, arguments)
- ReplParser: Handles REPL-specific concerns (tokenization, command resolution)
§2. Composability
Parsers compose naturally:
- ReplParser uses CliParser for argument parsing
- CliParser uses TypeParser for type conversion
- Each can be used independently when needed
§3. Error Clarity
All parsers provide detailed error messages with:
- Clear descriptions of what went wrong
- Suggestions for typos (via Levenshtein distance)
- Hints for correct usage
§Usage Examples
§CLI Mode (Direct Argument Parsing)
use dynamic_cli::parser::cli_parser::CliParser;
use dynamic_cli::config::schema::{CommandDefinition, ArgumentDefinition, ArgumentType};
let definition = CommandDefinition {
name: "process".to_string(),
aliases: vec![],
description: "Process files".to_string(),
required: false,
arguments: vec![
ArgumentDefinition {
name: "input".to_string(),
arg_type: ArgumentType::Path,
required: true,
description: "Input file".to_string(),
validation: vec![],
}
],
options: vec![],
implementation: "handler".to_string(),
};
let parser = CliParser::new(&definition);
let args = vec!["input.txt".to_string()];
let parsed = parser.parse(&args).unwrap();
assert_eq!(parsed.get("input"), Some(&"input.txt".to_string()));§REPL Mode (Interactive Parsing)
use dynamic_cli::parser::repl_parser::ReplParser;
use dynamic_cli::registry::CommandRegistry;
let registry = CommandRegistry::new();
// ... register commands ...
let parser = ReplParser::new(®istry);
// Parse user input
let line = "process input.txt --verbose";
let parsed = parser.parse_line(line).unwrap();
println!("Command: {}", parsed.command_name);
println!("Arguments: {:?}", parsed.arguments);§Type Parsing (Low-Level)
use dynamic_cli::parser::type_parser::{parse_integer, parse_bool};
let number = parse_integer("42").unwrap();
assert_eq!(number, 42);
let flag = parse_bool("yes").unwrap();
assert_eq!(flag, true);§Error Handling
All parsing functions return Result<T> where errors are instances
of [ParseError]. Common error scenarios:
-
Unknown command: User typed a non-existent command
Error: Unknown command: 'simulat' ? Did you mean: • simulate • validation -
Type mismatch: Value cannot be converted to expected type
Error: Failed to parse count as integer: 'abc' -
Missing argument: Required argument not provided
Error: Missing required argument: input for command 'process'
§Performance Considerations
- Type parsing: O(1) for most types, O(n) for string length
- CLI parsing: O(n) where n = number of arguments
- REPL parsing: O(m + n) where m = line length (tokenization), n = arguments
- Command resolution: O(1) via HashMap lookup in registry
§Thread Safety
All parsers are:
- Stateless: Can be used concurrently from multiple threads
- Borrowing: Use references to definitions/registry (no ownership)
- Reusable: Can parse multiple commands with the same parser instance
§Future Extensions
Potential enhancements for future versions:
- Support for subcommands (e.g.,
git commit) - Environment variable expansion
- Glob pattern matching for paths
- Command history and auto-completion hints
- Streaming parser for very large inputs
Re-exports§
pub use cli_parser::CliParser;pub use repl_parser::ParsedCommand;pub use repl_parser::ReplParser;
Modules§
- cli_
parser - CLI argument parser
- repl_
parser - REPL line parser
- type_
parser - Type parsing functions