wick_component_codegen/generate/templates/
op_outgoing.rs

1use itertools::Itertools;
2use proc_macro2::TokenStream;
3use quote::quote;
4use wick_interface_types::Field;
5
6use crate::generate::dependency::Dependency;
7use crate::generate::expand_type::expand_type;
8use crate::generate::ids::*;
9use crate::generate::{config, Direction};
10
11pub(crate) fn op_outgoing(config: &mut config::Config, name: &str, fields: &[Field]) -> TokenStream {
12  let outgoing_name = id(name);
13
14  let output_port_fields = fields
15    .iter()
16    .map(|i| {
17      let port_field_name = id(&snake(&i.name));
18      let port_type = expand_type(config, Direction::Out, false, config.raw, &i.ty);
19      quote! {pub(crate) #port_field_name: wick_packet::OutgoingPort<#port_type>}
20    })
21    .collect_vec();
22
23  let output_port_fields_mut = fields
24    .iter()
25    .map(|i| {
26      let port_field_name = id(&snake(&i.name));
27      quote! {&mut self.#port_field_name}
28    })
29    .collect_vec();
30
31  let output_ports_new = fields
32    .iter()
33    .map(|out| {
34      let port_name = &out.name;
35      let port_field_name = id(&snake(&out.name));
36      quote! {#port_field_name: wick_packet::OutgoingPort::new(#port_name, channel.clone())}
37    })
38    .collect_vec();
39
40  let single_output_impl = (fields.len() == 1).then(|| {
41    let output = fields.first().unwrap();
42    let name = id(&snake(output.name()));
43    quote! {
44      impl wick_component::SingleOutput for #outgoing_name {
45        fn single_output(&mut self) -> &mut dyn wick_packet::Port {
46          &mut self.#name
47        }
48      }
49    }
50  });
51
52  let outputs = config.output_structs.then(|| {
53    config.add_dep(Dependency::WickPacket);
54    config.add_dep(Dependency::WasmRsRx);
55    config.add_dep(Dependency::WasmRs);
56
57    quote! {
58      pub struct #outgoing_name {
59        pub(crate) channel: wasmrs_rx::FluxChannel<wasmrs::RawPayload, wasmrs::PayloadError>,
60        #[allow(unused)]
61        #(#output_port_fields),*
62      }
63
64      impl wick_component::Broadcast for #outgoing_name {
65        fn outputs_mut(&mut self) -> wick_packet::OutputIterator<'_>{
66          wick_packet::OutputIterator::new(vec![#(#output_port_fields_mut),*])
67        }
68      }
69
70      impl wick_packet::WasmRsChannel for #outgoing_name {
71        fn channel(&self) -> wasmrs_rx::FluxChannel<wasmrs::RawPayload, wasmrs::PayloadError> {
72          self.channel.clone()
73        }
74      }
75
76      #single_output_impl
77
78      impl #outgoing_name {
79        #[allow(unused)]
80        pub fn new() -> Self {
81          let channel = wasmrs_rx::FluxChannel::new();
82          Self {
83            #(#output_ports_new,)*
84            channel,
85          }
86        }
87        #[allow(unused)]
88        pub fn new_parts() -> (Self,wasmrs_rx::FluxReceiver<wasmrs::RawPayload, wasmrs::PayloadError>) {
89          let (channel,rx) = wasmrs_rx::FluxChannel::new_parts();
90          (Self {
91            #(#output_ports_new,)*
92            channel,
93          },rx)
94        }
95        #[allow(unused)]
96        pub fn with_channel(channel: wasmrs_rx::FluxChannel<wasmrs::RawPayload, wasmrs::PayloadError>) -> Self {
97          Self {
98            #(#output_ports_new,)*
99            channel,
100          }
101        }
102      }
103    }
104  });
105  quote! {#outputs}
106}
107
108pub(crate) fn op_simple_outgoing(config: &mut config::Config, name: &str, into: &str, fields: &[Field]) -> TokenStream {
109  let outgoing_name = id(name);
110  let impl_into_name = id(into);
111
112  let output_port_fields = fields
113    .iter()
114    .map(|i| {
115      let port_field_name = id(&snake(&i.name));
116      let port_type = expand_type(config, Direction::Out, false, false, &i.ty);
117      quote! {pub(crate) #port_field_name: #port_type}
118    })
119    .collect_vec();
120
121  let port_send = fields
122    .iter()
123    .map(|i| {
124      let port_field_name = id(&snake(&i.name));
125      quote! {inputs.#port_field_name.send(v.#port_field_name);}
126    })
127    .collect_vec();
128
129  let outputs = config.output_structs.then(|| {
130    config.add_dep(Dependency::WickPacket);
131    config.add_dep(Dependency::WasmRsRx);
132    config.add_dep(Dependency::WasmRs);
133
134    quote! {
135      pub struct #outgoing_name {
136        #[allow(unused)]
137        #(#output_port_fields),*
138      }
139      impl From<#outgoing_name> for #impl_into_name{
140        fn from(v:#outgoing_name) -> #impl_into_name {
141          let mut inputs =  #impl_into_name::new();
142          #(#port_send)*
143          inputs
144        }
145      }
146
147    }
148  });
149  quote! {#outputs}
150}