use serde::{Deserialize, Serialize};
pub use crate::extensions::heredoc_ast::HereDocInfo;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshProgram {
pub lists: Vec<ZshList>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshList {
pub sublist: ZshSublist,
pub flags: ListFlags,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct ListFlags {
pub async_: bool,
pub disown: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshSublist {
pub pipe: ZshPipe,
pub next: Option<(SublistOp, Box<ZshSublist>)>,
pub flags: SublistFlags,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SublistOp {
And, Or, }
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct SublistFlags {
pub coproc: bool,
pub not: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshPipe {
pub cmd: ZshCommand,
pub next: Option<Box<ZshPipe>>,
pub lineno: u64,
#[serde(default)]
pub merge_stderr: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ZshCommand {
Simple(ZshSimple),
Subsh(Box<ZshProgram>), Cursh(Box<ZshProgram>), For(ZshFor),
Case(ZshCase),
If(ZshIf),
While(ZshWhile),
Until(ZshWhile),
Repeat(ZshRepeat),
FuncDef(ZshFuncDef),
Time(Option<Box<ZshSublist>>),
Cond(ZshCond), Arith(String), Try(ZshTry), Redirected(Box<ZshCommand>, Vec<ZshRedir>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshSimple {
pub assigns: Vec<ZshAssign>,
pub words: Vec<String>,
pub redirs: Vec<ZshRedir>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshAssign {
pub name: String,
pub value: ZshAssignValue,
pub append: bool, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ZshAssignValue {
Scalar(String),
Array(Vec<String>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshRedir {
pub rtype: i32,
pub fd: i32,
pub name: String,
pub heredoc: Option<HereDocInfo>,
pub varid: Option<String>, #[serde(skip)]
pub heredoc_idx: Option<usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshFor {
pub var: String,
pub list: ForList,
pub body: Box<ZshProgram>,
#[serde(default)]
pub is_select: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ForList {
Words(Vec<String>),
CStyle {
init: String,
cond: String,
step: String,
},
Positional,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshCase {
pub word: String,
pub arms: Vec<CaseArm>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CaseArm {
pub patterns: Vec<String>,
pub body: ZshProgram,
pub terminator: CaseTerm,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CaseTerm {
Break, Continue, TestNext, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshIf {
pub cond: Box<ZshProgram>,
pub then: Box<ZshProgram>,
pub elif: Vec<(ZshProgram, ZshProgram)>,
pub else_: Option<Box<ZshProgram>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshWhile {
pub cond: Box<ZshProgram>,
pub body: Box<ZshProgram>,
pub until: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshRepeat {
pub count: String,
pub body: Box<ZshProgram>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshFuncDef {
pub names: Vec<String>,
pub body: Box<ZshProgram>,
pub tracing: bool,
#[serde(default)]
pub auto_call_args: Option<Vec<String>>,
#[serde(default)]
pub body_source: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ZshCond {
Not(Box<ZshCond>),
And(Box<ZshCond>, Box<ZshCond>),
Or(Box<ZshCond>, Box<ZshCond>),
Unary(String, String), Binary(String, String, String), Regex(String, String), }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZshTry {
pub try_block: Box<ZshProgram>,
pub always: Box<ZshProgram>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ZshParamFlag {
Lower, Upper, Capitalize, Join(String), JoinNewline, Split(String), SplitLines, SplitWords, Type, Words, Quote, QuoteIfNeeded, DoubleQuote, DollarQuote, QuoteBackslash, Unique, Reverse, Sort, NumericSort, IndexSort, Keys, Values, Length, CountChars, Expand, PromptExpand, PromptExpandFull, Visible, Directory, Head(usize), Tail(usize), PadLeft(usize, char), PadRight(usize, char), Width(usize), Match, Remove, Subscript, Parameter, Glob, At,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ListOp {
And, Or, Semi, Amp, Newline, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShellWord {
Literal(String),
Concat(Vec<ShellWord>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VarModifier {
Default(ShellWord),
DefaultAssign(ShellWord),
Error(ShellWord),
Alternate(ShellWord),
Length,
Substring(i64, Option<i64>),
RemovePrefix(ShellWord),
RemovePrefixLong(ShellWord),
RemoveSuffix(ShellWord),
RemoveSuffixLong(ShellWord),
Replace(ShellWord, ShellWord),
ReplaceAll(ShellWord, ShellWord),
ReplacePrefix(ShellWord, ShellWord),
ReplaceSuffix(ShellWord, ShellWord),
Upper,
Lower,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ShellCommand {
Simple(SimpleCommand),
Pipeline(Vec<ShellCommand>, bool),
List(Vec<(ShellCommand, ListOp)>),
Compound(CompoundCommand),
FunctionDef(String, Box<ShellCommand>),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimpleCommand {
pub assignments: Vec<(String, ShellWord, bool)>,
pub words: Vec<ShellWord>,
pub redirects: Vec<Redirect>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Redirect {
pub fd: Option<i32>,
pub op: RedirectOp,
pub target: ShellWord,
pub heredoc_content: Option<String>,
pub fd_var: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum RedirectOp {
Write,
Append,
Read,
ReadWrite,
Clobber,
DupRead,
DupWrite,
HereDoc,
HereString,
WriteBoth,
AppendBoth,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CompoundCommand {
BraceGroup(Vec<ShellCommand>),
Subshell(Vec<ShellCommand>),
If {
conditions: Vec<(Vec<ShellCommand>, Vec<ShellCommand>)>,
else_part: Option<Vec<ShellCommand>>,
},
For {
var: String,
words: Option<Vec<ShellWord>>,
body: Vec<ShellCommand>,
},
ForArith {
init: String,
cond: String,
step: String,
body: Vec<ShellCommand>,
},
While {
condition: Vec<ShellCommand>,
body: Vec<ShellCommand>,
},
Until {
condition: Vec<ShellCommand>,
body: Vec<ShellCommand>,
},
Case {
word: ShellWord,
cases: Vec<(Vec<ShellWord>, Vec<ShellCommand>, CaseTerminator)>,
},
Select {
var: String,
words: Option<Vec<ShellWord>>,
body: Vec<ShellCommand>,
},
Coproc {
name: Option<String>,
body: Box<ShellCommand>,
},
Repeat {
count: String,
body: Vec<ShellCommand>,
},
Try {
try_body: Vec<ShellCommand>,
always_body: Vec<ShellCommand>,
},
Arith(String),
WithRedirects(Box<ShellCommand>, Vec<Redirect>),
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum CaseTerminator {
Break,
Fallthrough,
Continue,
}