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}
28
29impl Block {
30 pub fn len(&self) -> usize {
31 self.pipelines.len()
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.pipelines.is_empty()
36 }
37
38 pub fn pipe_redirection(
39 &self,
40 working_set: &StateWorkingSet,
41 ) -> (Option<OutDest>, Option<OutDest>) {
42 if let Some(first) = self.pipelines.first() {
43 first.pipe_redirection(working_set)
44 } else {
45 (None, None)
46 }
47 }
48}
49
50impl Default for Block {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl Block {
57 pub fn new() -> Self {
58 Self {
59 signature: Box::new(Signature::new("")),
60 pipelines: vec![],
61 captures: vec![],
62 redirect_env: false,
63 ir_block: None,
64 span: None,
65 scope_bindings: None,
66 }
67 }
68
69 pub fn new_with_capacity(capacity: usize) -> Self {
70 Self {
71 signature: Box::new(Signature::new("")),
72 pipelines: Vec::with_capacity(capacity),
73 captures: vec![],
74 redirect_env: false,
75 ir_block: None,
76 span: None,
77 scope_bindings: None,
78 }
79 }
80
81 pub fn output_type(&self) -> Type {
82 match self.pipelines.last().and_then(|pl| pl.elements.last()) {
83 Some(pe) if pe.redirection.is_none() => pe.expr.ty.clone(),
84 Some(_) => Type::Any,
85 None => Type::Nothing,
86 }
87 }
88
89 pub fn replace_in_variable(
91 &mut self,
92 working_set: &mut StateWorkingSet<'_>,
93 new_var_id: VarId,
94 ) {
95 for pipeline in self.pipelines.iter_mut() {
96 if let Some(element) = pipeline.elements.first_mut() {
97 element.replace_in_variable(working_set, new_var_id);
98 }
99 }
100 }
101}
102
103impl<T> From<T> for Block
104where
105 T: Iterator<Item = Pipeline>,
106{
107 fn from(pipelines: T) -> Self {
108 Self {
109 signature: Box::new(Signature::new("")),
110 pipelines: pipelines.collect(),
111 captures: vec![],
112 redirect_env: false,
113 ir_block: None,
114 span: None,
115 scope_bindings: None,
116 }
117 }
118}