fn launch(cmd: &Cmd, stack: &mut Vec<Cmd>) {
    match cmd.command.as_str() {
        "exit" => exit(0),
        "!!" => {
            match stack.len() {
                0 => {
                    eprintln!("No history command.");
                },
                _ => {
                    let prev = Cmd {
                        command: stack.last().unwrap().command.clone(),
                        args: stack.last().unwrap().args.clone()
                    };
                    println!("{} {}", prev.command, format_args(&prev));
                    launch(&prev, stack);
                }
            }
        },
        "history" => {
            stack.push(Cmd {
                command: "history".into(),
                args: vec![]
            });
            for (i, c) in stack.iter().rev().enumerate() {
                println!("{} {} {}",
                         stack.len() - i,
                         c.command,
                         format_args(&c));
            }
        },
        _ => {
            let text = cmd.command.chars();
            if text.clone().next().unwrap() == '!' {
                let st = &cmd.command[1..];
                match st.parse::<usize>() {
                    Ok(n) => {
                        if n > stack.len() {
                            eprintln!("Index out of bound");
                        } else {
                            let cmd = stack[n - 1].clone();
                            println!("{} {}",
                                     cmd.command,
                                     format_args(&cmd));
                            launch(&cmd, stack);
                        }
                    },
                    Err(_) => { eprintln!("Wrong command");}
                };
            } else {
                match spawn_command(&cmd) {
                    true => {stack.push(cmd.clone())},
                    false => {}
                }
            }
        }
    }
}
// This function matches the input, and decide the following operation
// Up to now, rush support four types of commands:
// 1. exit, which can terminate the shell program
// 2. history, which can view all the successfully spawned commands
// 3. !! or ! + number, can directly spawn a command in history
// 4. Any available executables in PATH
This function matches the input, and decide the following operation
Up to now, rush support four types of commands:
1. exit, which can terminate the shell program
2. history, which can view all the successfully spawned commands
3.
This function matches the input and decide the following operation Up to now rush support four types of commands : 1 . exit which can terminate the shell program 2 . history which can view all the successfully spawned commands 3 .
fn launch(cmd: &Cmd, stack: &mut Vec<Cmd>) {
    match cmd.command.as_str() {
        "exit" => exit(0),
        "!!" => {
            match stack.len() {
                0 => {
                    eprintln!("No history command.");
                },
                _ => {
                    let prev = Cmd {
                        command: stack.last().unwrap().command.clone(),
                        args: stack.last().unwrap().args.clone()
                    };
                    println!("{} {}", prev.command, format_args(&prev));
                    launch(&prev, stack);
                }
            }
        },
        "history" => {
            stack.push(Cmd {
                command: "history".into(),
                args: vec![]
            });
            for (i, c) in stack.iter().rev().enumerate() {
                println!("{} {} {}",
                         stack.len() - i,
                         c.command,
                         format_args(&c));
            }
        },
        _ => {
            let text = cmd.command.chars();
            if text.clone().next().unwrap() == '!' {
                let st = &cmd.command[1..];
                match st.parse::<usize>() {
                    Ok(n) => {
                        if n > stack.len() {
                            eprintln!("Index out of bound");
                        } else {
                            let cmd = stack[n - 1].clone();
                            println!("{} {}",
                                     cmd.command,
                                     format_args(&cmd));
                            launch(&cmd, stack);
                        }
                    },
                    Err(_) => { eprintln!("Wrong command");}
                };
            } else {
                match spawn_command(&cmd) {
                    true => {stack.push(cmd.clone())},
                    false => {}
                }
            }
        }
    }
}
fn launch ( cmd : & Cmd , stack : & mut Vec < Cmd > ) { match cmd . command . as_str ( ) { " " => exit ( 0 ) , " " => { match stack . len ( ) { 0 => { eprintln ! ( " " ) ; } , _ => { let prev = Cmd { command : stack . last ( ) . unwrap ( ) . command . clone ( ) , args : stack . last ( ) . unwrap ( ) . args . clone ( ) } ; println ! ( " " prev command format_args ( prev ) ) ; launch ( & prev , stack ) ; } } } , " " => { stack . push ( Cmd { command : " " . into ( ) , args : vec ! [ ] } ) ; for ( i , c ) in stack . iter ( ) . rev ( ) . enumerate ( ) { println ! ( " " stack len ( ) i c command format_args ( c ) ) ; } } , _ => { let text = cmd . command . chars ( ) ; if text . clone ( ) . next ( ) . unwrap ( ) == '!' { let st = & cmd . command [ 1 .. ] ; match st . parse :: < usize > ( ) { Ok ( n ) => { if n > stack . len ( ) { eprintln ! ( " " ) ; } else { let cmd = stack [ n - 1 ] . clone ( ) ; println ! ( " " cmd command format_args ( cmd ) ) ; launch ( & cmd , stack ) ; } } , Err ( _ ) => { eprintln ! ( " " ) ; } } ; } else { match spawn_command ( & cmd ) { true => { stack . push ( cmd . clone ( ) ) } , false => { } } } } } }
This function matches the input, and decide the following operation
Up to now, rush support four types of commands:
1. exit, which can terminate the shell program
2. history, which can view all the successfully spawned commands
3.
This function matches the input and decide the following operation Up to now rush support four types of commands : 1 . exit which can terminate the shell program 2 . history which can view all the successfully spawned commands 3 .
cmd
&Cmd
stack
&mut Vec<Cmd>
cmd
&Cmd
stack
&mut Vec<Cmd>