1mod parser;
2mod process;
3mod proc_env;
4mod proc_var;
5
6pub type FunResult = std::io::Result<String>;
7pub type CmdResult = std::io::Result<()>;
8pub use proc_env::Env;
9pub use parser::Parser;
10
11use std::collections::{HashMap, VecDeque};
12
13pub fn run_cmd<S: Into<String>>(cmds: S) -> CmdResult {
14 Parser::new(cmds.into()).parse().run_cmd()
15}
16
17pub fn run_fun<S: Into<String>>(cmds: S) -> FunResult {
18 Parser::new(cmds.into()).parse().run_fun()
19}
20
21pub fn run_cmd_with_ctx(
23 code: &str,
24 fn_sym_table: impl FnOnce(&mut HashMap<&str, String>),
25 fn_str_lits: impl FnOnce(&mut VecDeque<String>),
26) -> CmdResult {
27 parse_cmds_with_ctx(code, fn_sym_table, fn_str_lits).run_cmd()
28}
29
30pub fn run_fun_with_ctx(
31 code: &str,
32 fn_sym_table: impl FnOnce(&mut HashMap<&str, String>),
33 fn_str_lits: impl FnOnce(&mut VecDeque<String>),
34) -> FunResult {
35 parse_cmds_with_ctx(code, fn_sym_table, fn_str_lits).run_fun()
36}
37
38fn parse_cmds_with_ctx(
39 code: &str,
40 fn_sym_table: impl FnOnce(&mut HashMap<&str, String>),
41 fn_str_lits: impl FnOnce(&mut VecDeque<String>),
42) -> crate::process::GroupCmds {
43 let mut sym_table = HashMap::new();
44 fn_sym_table(&mut sym_table);
45
46 let mut str_lits = VecDeque::new();
47 fn_str_lits(&mut str_lits);
48
49 Parser::new(code)
50 .with_sym_table(sym_table)
51 .with_lits(str_lits)
52 .parse()
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn test_optional_args() {
61 let show_all = true;
62 let show_details = true;
63
64 let mut ls_opts = String::new();
65 if show_all {
66 ls_opts += " -a";
67 }
68 if show_details {
69 ls_opts += " -l";
70 }
71 let ls_cmd = format!(r#"ls {} | grep "\.\.$" | awk "{{print $9}}""#, ls_opts);
72 assert_eq!(run_fun(ls_cmd).unwrap(), "..");
73 }
74}