dfir_lang/graph/ops/
zip_longest.rs
1use quote::quote_spanned;
2use syn::parse_quote;
3
4use super::{
5 DelayType, OpInstGenerics, OperatorCategory, OperatorConstraints, OperatorInstance,
6 OperatorWriteOutput, Persistence, WriteContextArgs, RANGE_0, RANGE_1,
7};
8use crate::diagnostic::{Diagnostic, Level};
9
10pub const ZIP_LONGEST: OperatorConstraints = OperatorConstraints {
26 name: "zip_longest",
27 categories: &[OperatorCategory::MultiIn],
28 hard_range_inn: &(2..=2),
29 soft_range_inn: &(2..=2),
30 hard_range_out: RANGE_1,
31 soft_range_out: RANGE_1,
32 num_args: 0,
33 persistence_args: &(0..=1),
34 type_args: RANGE_0,
35 is_external_input: false,
36 has_singleton_output: false,
37 flo_type: None,
38 ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })),
39 ports_out: None,
40 input_delaytype_fn: |_| Some(DelayType::Stratum),
41 write_fn: |&WriteContextArgs {
42 root,
43 op_span,
44 ident,
45 is_pull,
46 inputs,
47 op_name,
48 op_inst:
49 OperatorInstance {
50 generics:
51 OpInstGenerics {
52 persistence_args, ..
53 },
54 ..
55 },
56 ..
57 },
58 diagnostics| {
59 assert!(is_pull);
60
61 let persistence = match persistence_args[..] {
62 [] => Persistence::Tick,
63 [a] => a,
64 _ => unreachable!(),
65 };
66 if Persistence::Tick != persistence {
67 diagnostics.push(Diagnostic::spanned(
68 op_span,
69 Level::Error,
70 format!("`{}()` can only have `'tick` persistence.", op_name),
71 ));
72 }
74
75 let lhs = &inputs[0];
76 let rhs = &inputs[1];
77 let write_iterator = quote_spanned! {op_span=>
78 let #ident = #root::itertools::Itertools::zip_longest(#lhs, #rhs);
79 };
80
81 Ok(OperatorWriteOutput {
82 write_iterator,
83 ..Default::default()
84 })
85 },
86};