Skip to main content

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}