dfir_lang/graph/ops/
inspect.rs

1use quote::quote_spanned;
2
3use super::{
4    OperatorCategory, OperatorConstraints, OperatorWriteOutput,
5    WriteContextArgs, RANGE_0, RANGE_1,
6};
7
8/// > Arguments: A single closure `FnMut(&Item)`.
9///
10/// An operator which allows you to "inspect" each element of a stream without
11/// modifying it. The closure is called on a reference to each item. This is
12/// mainly useful for debugging as in the example below, and it is generally an
13/// anti-pattern to provide a closure with side effects.
14///
15/// > Note: The closure has access to the [`context` object](surface_flows.mdx#the-context-object).
16///
17/// ```dfir
18/// source_iter([1, 2, 3, 4])
19///     -> inspect(|x| println!("{}", x))
20///     -> assert_eq([1, 2, 3, 4]);
21/// ```
22pub const INSPECT: OperatorConstraints = OperatorConstraints {
23    name: "inspect",
24    categories: &[OperatorCategory::Map],
25    hard_range_inn: RANGE_1,
26    soft_range_inn: RANGE_1,
27    hard_range_out: &(0..=1),
28    soft_range_out: &(0..=1),
29    num_args: 1,
30    persistence_args: RANGE_0,
31    type_args: RANGE_0,
32    is_external_input: false,
33    has_singleton_output: false,
34    flo_type: None,
35    ports_inn: None,
36    ports_out: None,
37    input_delaytype_fn: |_| None,
38    write_fn: |&WriteContextArgs {
39                   root,
40                   op_span,
41                   ident,
42                   inputs,
43                   outputs,
44                   is_pull,
45                   arguments,
46                   ..
47               },
48               _| {
49        let write_iterator = if is_pull {
50            let input = &inputs[0];
51            quote_spanned! {op_span=>
52                let #ident = #input.inspect(#arguments);
53            }
54        } else if outputs.is_empty() {
55            quote_spanned! {op_span=>
56                let #ident = #root::pusherator::inspect::Inspect::new(#arguments, #root::pusherator::null::Null::new());
57            }
58        } else {
59            let output = &outputs[0];
60            quote_spanned! {op_span=>
61                let #ident = #root::pusherator::inspect::Inspect::new(#arguments, #output);
62            }
63        };
64        Ok(OperatorWriteOutput {
65            write_iterator,
66            ..Default::default()
67        })
68    },
69};