1use super::Pipeline;
2use crate::{
3 OutDest, Signature, Span, Type, VarId,
4 engine::{ScopeBindings, StateWorkingSet},
5 ir::IrBlock,
6};
7use serde::{Deserialize, Serialize};
8use std::sync::Arc;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct Block {
12 pub signature: Box<Signature>,
13 pub pipelines: Vec<Pipeline>,
14 pub captures: Vec<(VarId, Span)>,
15 pub redirect_env: bool,
16 pub ir_block: Option<IrBlock>,
18 pub span: Option<Span>, #[serde(skip)]
26 pub scope_bindings: Option<Arc<ScopeBindings>>,
27 #[serde(skip)]
32 pub parsed_scoped: bool,
33}
34
35impl Block {
36 pub fn len(&self) -> usize {
37 self.pipelines.len()
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.pipelines.is_empty()
42 }
43
44 pub fn pipe_redirection(
45 &self,
46 working_set: &StateWorkingSet,
47 ) -> (Option<OutDest>, Option<OutDest>) {
48 if let Some(first) = self.pipelines.first() {
49 first.pipe_redirection(working_set)
50 } else {
51 (None, None)
52 }
53 }
54}
55
56impl Default for Block {
57 fn default() -> Self {
58 Self::new()
59 }
60}
61
62impl Block {
63 pub fn new() -> Self {
64 Self {
65 signature: Box::new(Signature::new("")),
66 pipelines: vec![],
67 captures: vec![],
68 redirect_env: false,
69 ir_block: None,
70 span: None,
71 scope_bindings: None,
72 parsed_scoped: false,
73 }
74 }
75
76 pub fn new_with_capacity(capacity: usize) -> Self {
77 Self {
78 signature: Box::new(Signature::new("")),
79 pipelines: Vec::with_capacity(capacity),
80 captures: vec![],
81 redirect_env: false,
82 ir_block: None,
83 span: None,
84 scope_bindings: None,
85 parsed_scoped: false,
86 }
87 }
88
89 pub fn output_type(&self) -> Type {
90 match self.pipelines.last().and_then(|pl| pl.elements.last()) {
91 Some(pe) if pe.redirection.is_none() => pe.expr.ty.clone(),
92 Some(_) => Type::Any,
93 None => Type::Nothing,
94 }
95 }
96
97 pub fn replace_in_variable(
99 &mut self,
100 working_set: &mut StateWorkingSet<'_>,
101 new_var_id: VarId,
102 ) {
103 for pipeline in self.pipelines.iter_mut() {
104 if let Some(element) = pipeline.elements.first_mut() {
105 element.replace_in_variable(working_set, new_var_id);
106 }
107 }
108 }
109}
110
111impl<T> From<T> for Block
112where
113 T: Iterator<Item = Pipeline>,
114{
115 fn from(pipelines: T) -> Self {
116 Self {
117 signature: Box::new(Signature::new("")),
118 pipelines: pipelines.collect(),
119 captures: vec![],
120 redirect_env: false,
121 ir_block: None,
122 span: None,
123 scope_bindings: None,
124 parsed_scoped: false,
125 }
126 }
127}