use crate::command::command_builder::CommandBuilder; use crate::command::command_sequence::CommandSequence; fn parse_quote(characters: &mut Vec) -> Result { if characters.is_empty() { Err(UnmatchedQuoteError) } else { let mut quoted_arg = String::default(); let mut current_char = characters.pop().unwrap(); while !characters.is_empty() && current_char != '\'' { quoted_arg.push(current_char); current_char = characters.pop().unwrap(); } Ok(quoted_arg) } } fn parse_main(characters: &mut Vec, current_arg: &mut String) -> Vec { if characters.is_empty() { vec![] } else { let current_char = characters.pop().unwrap(); if current_char.is_whitespace() { if !current_arg.is_empty() { let mut argv: Vec = vec![current_arg.clone()]; argv.append(&mut parse_main(characters, &mut String::from(""))); argv } else { parse_main(characters, current_arg) } } else if current_char == '\'' { let mut argv = vec![parse_quote(characters).unwrap()]; argv.append(&mut parse_main(characters, &mut String::default())); argv } else if current_char == ';' { vec![] } else { current_arg.push(current_char); parse_main(characters, current_arg) } } } pub fn parse(line: String) -> CommandSequence { let mut characters: Vec = line.chars().rev().collect(); let mut command_sequence = CommandSequence::new(); while !characters.is_empty() { let argv = parse_main(&mut characters, &mut String::default()); if !argv.is_empty() { let command = CommandBuilder::new(argv).build(); command_sequence.add(command); } } command_sequence } #[derive(Debug)] struct UnmatchedQuoteError;