Brijesh's Git Server — bsh @ 92d54f18eceb62f97feed88dcf68a482ee75d817

my own shell program

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 })
}