cmd_lib_core/
lib.rs

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
21// APIs For proc_macros
22pub 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}