cc_toolgate/parse/types.rs
1//! Types produced by the shell parser and consumed by the eval layer.
2
3/// Shell operator separating consecutive pipeline segments.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum Operator {
6 /// `&&` — run next only if previous succeeded
7 And,
8 /// `||` — run next only if previous failed
9 Or,
10 /// `;` — run next unconditionally
11 Semi,
12 /// `|` — pipe stdout
13 Pipe,
14 /// `|&` — pipe stdout+stderr
15 PipeErr,
16}
17
18impl Operator {
19 /// The operator's shell syntax.
20 pub fn as_str(&self) -> &'static str {
21 match self {
22 Operator::And => "&&",
23 Operator::Or => "||",
24 Operator::Semi => ";",
25 Operator::Pipe => "|",
26 Operator::PipeErr => "|&",
27 }
28 }
29}
30
31/// A single evaluable command within a compound pipeline.
32///
33/// `command` contains the text that will be passed to `base_command()`,
34/// `tokenize()`, and `has_output_redirection()` in the eval layer.
35/// Any `$()`, backtick, or process substitution spans have been replaced
36/// with `__SUBST__` placeholders.
37#[derive(Debug, Clone)]
38pub struct ShellSegment {
39 /// Command text, with substitution spans replaced by `__SUBST__`.
40 pub command: String,
41
42 /// Output redirection detected on a wrapping construct.
43 ///
44 /// When the parser extracts commands from inside a control flow block
45 /// that has output redirection (e.g. `for ... done > file`), the
46 /// redirect is not present in the segment's `command` text. This field
47 /// carries the redirection so the eval layer can escalate the decision.
48 ///
49 /// For segments where the redirect IS in the command text (e.g.
50 /// `echo hi > file`), this field may also be set but is redundant —
51 /// `CommandContext::from_command` will independently detect it.
52 pub redirection: Option<Redirection>,
53}
54
55/// Describes an output redirection that may mutate filesystem state.
56#[derive(Debug, Clone, PartialEq, Eq)]
57pub struct Redirection {
58 /// Human-readable description, e.g. `"output redirection (>)"`.
59 pub description: String,
60}
61
62/// A fully decomposed compound command: segments interleaved with operators.
63///
64/// For a simple command like `ls -la`, there is one segment and no operators.
65/// For `a && b | c`, there are three segments and two operators (`&&`, `|`).
66#[derive(Debug, Clone)]
67pub struct ParsedPipeline {
68 /// The command segments (one per simple command in the pipeline/list).
69 pub segments: Vec<ShellSegment>,
70 /// Operators between consecutive segments (`&&`, `||`, `;`, `|`, `|&`).
71 pub operators: Vec<Operator>,
72}