dfir_lang/graph/ops/
filter_map.rs

1use quote::quote_spanned;
2
3use super::{
4    OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs,
5    RANGE_0, RANGE_1,
6};
7
8/// > 1 input stream, 1 output stream
9///
10/// An operator that both filters and maps. It yields only the items for which the supplied closure returns `Some(value)`.
11///
12/// > Note: The closure has access to the [`context` object](surface_flows.mdx#the-context-object).
13///
14/// ```dfir
15/// source_iter(vec!["1", "hello", "world", "2"])
16///     -> filter_map(|s| s.parse::<usize>().ok())
17///     -> assert_eq([1, 2]);
18/// ```
19pub const FILTER_MAP: OperatorConstraints = OperatorConstraints {
20    name: "filter_map",
21    categories: &[OperatorCategory::Filter],
22    hard_range_inn: RANGE_1,
23    soft_range_inn: RANGE_1,
24    hard_range_out: RANGE_1,
25    soft_range_out: RANGE_1,
26    num_args: 1,
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                   ident,
39                   inputs,
40                   outputs,
41                   is_pull,
42                   arguments,
43                   ..
44               },
45               _| {
46        let write_iterator = if is_pull {
47            let input = &inputs[0];
48            quote_spanned! {op_span=>
49                let #ident = #input.filter_map(#arguments);
50            }
51        } else {
52            let output = &outputs[0];
53            quote_spanned! {op_span=>
54                let #ident = #root::pusherator::filter_map::FilterMap::new(#arguments, #output);
55            }
56        };
57        Ok(OperatorWriteOutput {
58            write_iterator,
59            ..Default::default()
60        })
61    },
62};