use crate::shell::common::types::{Cmd, CmdPart, Arg, Redirect, CmdPartSection, Assignment, CmdType};
grammar;
match {
">" => REDIRECT_OUT,
"<" => REDIRECT_IN,
"|" => PIPE,
"=" => EQUALS,
"set" => SET,
r#""[^"]*""# => STRING,
r#"'[^']*'"# => SINGLE_QUOTED_STRING,
r#"[^\s|"$()=#']+"# => WORD,
r#"\s*"# => {},
}
pub Command: Cmd = {
<p0:CmdType> <prest:(PIPE <CmdType>)*> => Cmd{
parts: vec![p0].into_iter().chain(prest.into_iter()).collect(),
}
}
CmdType: CmdType = {
<part: Part> => CmdType::Cmd(part),
SET <var: WORD> EQUALS <ass: Assignment> => CmdType::Variable(String::from(var), match ass {
Assignment::Word(w) => w,
Assignment::String(s) => s
})
}
Part: CmdPart = {
<redirects: Redirect*> <cmd: WORD> <args: CmdPartSection*> => CmdPart {
cmd: String::from(cmd),
args: args.clone().into_iter().filter_map(|v| match v {
CmdPartSection::Redirect(_) => None,
CmdPartSection::Arg(arg) => Some(arg),
}).collect(),
redirects: [redirects, args.into_iter().filter_map(|v| match v {
CmdPartSection::Redirect(r) => Some(r),
CmdPartSection::Arg(_) => None,
}).collect()].concat(),
},
}
CmdPartSection: CmdPartSection = {
Arg => CmdPartSection::Arg(<>),
Redirect => CmdPartSection::Redirect(<>),
}
Arg: Arg = {
<word: WORD> EQUALS <ass: Assignment> => Arg::Assignment(String::from(word), ass),
<ass: Assignment> => match ass {
Assignment::String(s) => Arg::String(s),
Assignment::Word(w) => Arg::Word(w),
}
}
Redirect: Redirect = {
REDIRECT_IN <f: WORD> => Redirect::In(String::from(f)),
REDIRECT_OUT <f: WORD> => Redirect::Out(String::from(f))
}
Assignment: Assignment = {
SINGLE_QUOTED_STRING => Assignment::String(String::from(<>.strip_prefix("'").unwrap().strip_suffix("'").unwrap())),
STRING => Assignment::String(String::from(<>.strip_prefix('"').unwrap().strip_suffix('"').unwrap())),
WORD => Assignment::Word(String::from(<>)),
}