src/parser.rs (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
use std::str::FromStr; pub struct ParsedCommand { pub command: String, pub args: Vec<String>, } pub fn parse(input: &str) -> Result<ParsedCommand, &'static str> { let mut command = String::new(); let mut args = Vec::new(); let mut current_arg = String::new(); let mut in_single_quote = false; let mut in_double_quote = false; let chars = input.chars().collect::<Vec<_>>(); for c in chars { match c { '\'' if !in_double_quote => { in_single_quote = !in_single_quote; // Toggle single quote state } '"' if !in_single_quote => { in_double_quote = !in_double_quote; // Toggle double quote state } ' ' if !in_single_quote && !in_double_quote => { // If we encounter a space and we're not in quotes, we finalize the current argument if !current_arg.is_empty() { if command.is_empty() { command = current_arg.clone(); } else { args.push(current_arg.clone()); } current_arg.clear(); } } _ => { current_arg.push(c); // Add character to the current argument } } } // Finalize the last argument if !current_arg.is_empty() { if command.is_empty() { command = current_arg.clone(); } else { args.push(current_arg); } } Ok(ParsedCommand { command, args }) } |