dfir_lang/graph/ops/
tee.rs
1use quote::{quote_spanned, ToTokens};
2
3use super::{
4 OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, RANGE_1,
5 RANGE_ANY,
6};
7
8pub const TEE: OperatorConstraints = OperatorConstraints {
20 name: "tee",
21 categories: &[OperatorCategory::MultiOut],
22 hard_range_inn: RANGE_1,
23 soft_range_inn: RANGE_1,
24 hard_range_out: RANGE_ANY,
25 soft_range_out: &(2..),
26 num_args: 0,
27 persistence_args: RANGE_0,
28 type_args: RANGE_0,
29 is_external_input: false,
30 has_singleton_output: false,
31 flo_type: None,
32 ports_inn: None,
33 ports_out: None,
34 input_delaytype_fn: |_| None,
35 write_fn: |&WriteContextArgs {
36 root,
37 op_span,
38 op_name,
39 ident,
40 inputs,
41 outputs,
42 is_pull,
43 ..
44 },
45 _| {
46 let write_iterator = if !is_pull {
47 let tees = outputs
48 .iter()
49 .rev()
50 .map(|i| i.to_token_stream())
51 .reduce(|b, a| quote_spanned! {op_span=> #root::pusherator::tee::Tee::new(#a, #b) })
52 .unwrap_or_else(
53 || quote_spanned! {op_span=> #root::pusherator::for_each::ForEach::new(std::mem::drop) },
54 );
55 quote_spanned! {op_span=>
56 let #ident = #tees;
57 }
58 } else {
59 assert_eq!(1, inputs.len());
61 assert_eq!(
62 1,
63 outputs.len(),
64 "`{}()` marked as pull should have exactly one output, actually has {}. This is a bug.",
65 op_name,
66 outputs.len()
67 );
68 let input = &inputs[0];
69 quote_spanned! {op_span=>
70 let #ident = #input;
71 }
72 };
73 Ok(OperatorWriteOutput {
74 write_iterator,
75 ..Default::default()
76 })
77 },
78};