dfir_lang/graph/ops/
filter.rs

1use quote::quote_spanned;
2
3use super::{
4    OperatorCategory, OperatorConstraints, OperatorWriteOutput,
5    WriteContextArgs, RANGE_0, RANGE_1,
6};
7
8/// Filter outputs a subsequence of the items it receives at its input, according to a
9/// Rust boolean closure passed in as an argument.
10///
11/// The closure receives a reference `&T` rather than an owned value `T` because filtering does
12/// not modify or take ownership of the values. If you need to modify the values while filtering
13/// use [`filter_map`](#filter_map) instead.
14///
15/// > Note: The closure has access to the [`context` object](surface_flows.mdx#the-context-object).
16///
17/// ```dfir
18/// source_iter(vec!["hello", "world"]) -> filter(|x| x.starts_with('w'))
19///     -> assert_eq(["world"]);
20/// ```
21pub const FILTER: OperatorConstraints = OperatorConstraints {
22    name: "filter",
23    categories: &[OperatorCategory::Filter],
24    hard_range_inn: RANGE_1,
25    soft_range_inn: RANGE_1,
26    hard_range_out: RANGE_1,
27    soft_range_out: RANGE_1,
28    num_args: 1,
29    persistence_args: RANGE_0,
30    type_args: RANGE_0,
31    is_external_input: false,
32    has_singleton_output: false,
33    flo_type: None,
34    ports_inn: None,
35    ports_out: None,
36    input_delaytype_fn: |_| None,
37    write_fn: |&WriteContextArgs {
38                   root,
39                   op_span,
40                   ident,
41                   inputs,
42                   outputs,
43                   is_pull,
44                   arguments,
45                   ..
46               },
47               _| {
48        let write_iterator = if is_pull {
49            let input = &inputs[0];
50            quote_spanned! {op_span=>
51                let #ident = #input.filter(#arguments);
52            }
53        } else {
54            let output = &outputs[0];
55            quote_spanned! {op_span=>
56                let #ident = #root::pusherator::filter::Filter::new(#arguments, #output);
57            }
58        };
59        Ok(OperatorWriteOutput {
60            write_iterator,
61            ..Default::default()
62        })
63    },
64};