ion_shell_parser/parsing/language_items/
commands.rs

1pub use command_expression::{
2    CommandExpression, FileInteractionWithCommand, FileRedirectContext, RawCommandExpression,
3};
4pub use executable_builin::{Builtin, ExecutableOrBuiltin};
5pub use pipe_command::{NextPipedCommand, PipeOfCommands, PipeOperatorContext};
6
7mod command_expression;
8mod executable_builin;
9mod pipe_command;
10
11use crate::{
12    macros::{gen_impl_dbg_txt, gen_impl_has_location},
13    parsing::{whole_range_from_seq, HasLocation, RangeDebugText},
14    Range,
15};
16
17use super::{
18    command_operators::{DetachOperator, LogicalChainOperator},
19    language_item::CanHaveSourceBuiltin,
20    variables::VariableReference,
21    FoundSourceBuiltin, HasCommandInvocation, HasVariableReference, HasWarnings,
22};
23
24#[derive(Debug, PartialEq)]
25pub struct CommandChain {
26    first: PipeOfCommands,
27    rest: Vec<NextCommand>,
28    detach: Option<DetachOperatorContext>,
29}
30
31gen_impl_dbg_txt! {CommandChain # first, detach @ rest}
32impl HasLocation for CommandChain {
33    fn location(&self) -> Range {
34        let start = self.first.location();
35        let end = self
36            .detach
37            .as_ref()
38            .map(|e| e.location())
39            .unwrap_or_else(|| whole_range_from_seq(&self.rest).unwrap_or(start));
40        Range::from_start_end_internal(start, end)
41    }
42}
43impl HasWarnings for CommandChain {
44    fn all_warnings(&self, on_found: &mut dyn FnMut(&crate::parsing::ParsingError)) {
45        self.first().all_warnings(on_found);
46        self.rest().all_warnings(on_found);
47    }
48}
49
50impl HasCommandInvocation for CommandChain {
51    fn command_invocation(&self, on_found: &mut dyn FnMut(Range)) {
52        self.first.command_invocation(on_found);
53        self.rest.as_slice().command_invocation(on_found);
54    }
55}
56
57impl HasVariableReference for CommandChain {
58    fn var_references(&self, on_found: &mut dyn FnMut(&VariableReference)) {
59        self.first.var_references(on_found);
60        self.rest().var_references(on_found);
61    }
62}
63
64impl CanHaveSourceBuiltin for CommandChain {
65    fn source_calls(&self, mut on_found: impl FnMut(FoundSourceBuiltin)) {
66        self.first.source_calls(&mut on_found);
67        self.rest
68            .iter()
69            .for_each(|next| next.source_calls(&mut on_found));
70    }
71}
72
73impl CommandChain {
74    pub fn new(
75        first: PipeOfCommands,
76        rest: Vec<NextCommand>,
77        detach: Option<DetachOperatorContext>,
78    ) -> Self {
79        Self {
80            first,
81            rest,
82            detach,
83        }
84    }
85
86    pub fn first(&self) -> &PipeOfCommands {
87        &self.first
88    }
89
90    pub fn rest(&self) -> &[NextCommand] {
91        &self.rest
92    }
93
94    pub fn detach(&self) -> Option<&DetachOperatorContext> {
95        self.detach.as_ref()
96    }
97}
98
99#[derive(Debug, PartialEq)]
100pub struct NextCommand {
101    chain_operator: ChainLogicalOperatorContext,
102    command: PipeOfCommands,
103}
104
105impl HasWarnings for NextCommand {
106    fn all_warnings(&self, on_found: &mut dyn FnMut(&crate::parsing::ParsingError)) {
107        self.command.all_warnings(on_found);
108    }
109}
110
111impl HasCommandInvocation for NextCommand {
112    fn command_invocation(&self, on_found: &mut dyn FnMut(Range)) {
113        self.command.command_invocation(on_found);
114    }
115}
116
117impl HasVariableReference for NextCommand {
118    fn var_references(&self, on_found: &mut dyn FnMut(&VariableReference)) {
119        self.command.var_references(on_found);
120    }
121}
122
123impl CanHaveSourceBuiltin for NextCommand {
124    fn source_calls(&self, on_found: impl FnMut(super::language_item::FoundSourceBuiltin)) {
125        self.command.source_calls(on_found);
126    }
127}
128
129impl NextCommand {
130    pub fn new(chain_operator: ChainLogicalOperatorContext, command: PipeOfCommands) -> Self {
131        Self {
132            chain_operator,
133            command,
134        }
135    }
136}
137
138gen_impl_dbg_txt! {NextCommand, command, chain_operator}
139gen_impl_has_location! {NextCommand, chain_operator <=> command}
140
141#[derive(Debug, PartialEq)]
142pub struct DetachOperatorContext {
143    range: RangeDebugText,
144    operator: DetachOperator,
145}
146
147impl DetachOperatorContext {
148    pub fn new(range: Range, operator: DetachOperator) -> Self {
149        let range = range.into();
150        Self { range, operator }
151    }
152
153    pub fn operator(&self) -> DetachOperator {
154        self.operator
155    }
156}
157
158gen_impl_dbg_txt! {DetachOperatorContext, range}
159gen_impl_has_location! {DetachOperatorContext, range}
160
161#[derive(Debug, PartialEq)]
162pub struct ChainLogicalOperatorContext {
163    range: RangeDebugText,
164    chain_operator: LogicalChainOperator,
165}
166
167impl ChainLogicalOperatorContext {
168    pub fn new(range: Range, chain_operator: LogicalChainOperator) -> Self {
169        let range = range.into();
170        Self {
171            range,
172            chain_operator,
173        }
174    }
175
176    pub fn chain_operator(&self) -> LogicalChainOperator {
177        self.chain_operator
178    }
179}
180
181gen_impl_dbg_txt! {ChainLogicalOperatorContext, range}
182gen_impl_has_location! {ChainLogicalOperatorContext, range}