mpst_seq_proc/macros_simple/roles/
create_normal_role_short.rs1use proc_macro2::{Span, TokenStream};
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::{Ident, Result};
5
6#[derive(Debug)]
7pub(crate) struct CreateNormalRoleShort {
8 role: Ident,
9}
10
11impl Parse for CreateNormalRoleShort {
12 fn parse(input: ParseStream) -> Result<Self> {
13 let role = Ident::parse(input)?;
14
15 Ok(CreateNormalRoleShort { role })
16 }
17}
18
19impl From<CreateNormalRoleShort> for TokenStream {
20 fn from(input: CreateNormalRoleShort) -> TokenStream {
21 input.expand()
22 }
23}
24
25impl CreateNormalRoleShort {
26 fn expand(&self) -> TokenStream {
27 let role = &self.role;
28
29 let concatenated_role = format!("Role{role}");
32 let role_name = Ident::new(&concatenated_role, Span::call_site());
33 let concatenated_dual = format!("Role{role}Dual");
35 let dual_name = Ident::new(&concatenated_dual, Span::call_site());
36
37 quote! {
38 #[derive(Debug)]
42 struct #role_name<R>
43 where
44 R: mpstthree::role::Role,
45 R::Dual: mpstthree::role::Role,
46 {
47 sender: crossbeam_channel::Sender<R::Dual>,
48 }
49
50 #[derive(Debug)]
54 struct #dual_name<R>
55 where
56 R: mpstthree::role::Role,
57 R::Dual: mpstthree::role::Role,
58 {
59 sender: crossbeam_channel::Sender<R::Dual>,
60 }
61
62 impl<R: mpstthree::role::Role> mpstthree::role::Role for #role_name<R> {
66 type Dual = #dual_name::<<R as mpstthree::role::Role>::Dual>;
67
68 #[doc(hidden)]
69 fn new() -> (Self, Self::Dual) {
70 let (sender_normal, _) = crossbeam_channel::bounded::<R>(1);
71 let (sender_dual, _) = crossbeam_channel::bounded::<R::Dual>(1);
72
73 (
74 #role_name {
75 sender: sender_dual,
76 },
77 #dual_name {
78 sender: sender_normal,
79 },
80 )
81 }
82
83 #[doc(hidden)]
84 fn head_str() -> String {
85 String::from(stringify!(#role_name))
86 }
87
88 #[doc(hidden)]
89 fn tail_str() -> String {
90 format!(
91 "{}<{}>",
92 <R as mpstthree::role::Role>::head_str(),
93 <R as mpstthree::role::Role>::tail_str()
94 )
95 }
96
97 #[doc(hidden)]
98 fn self_head_str(&self) -> String {
99 String::from(stringify!(#role_name))
100 }
101
102 #[doc(hidden)]
103 fn self_tail_str(&self) -> String {
104 format!(
105 "{}<{}>",
106 <R as mpstthree::role::Role>::head_str(),
107 <R as mpstthree::role::Role>::tail_str()
108 )
109 }
110 }
111
112 impl<R: mpstthree::role::Role> mpstthree::role::Role for #dual_name<R> {
116 type Dual = #role_name::<<R as mpstthree::role::Role>::Dual>;
117
118 #[doc(hidden)]
119 fn new() -> (Self, Self::Dual) {
120 let (sender_normal, _) = crossbeam_channel::bounded::<R>(1);
121 let (sender_dual, _) = crossbeam_channel::bounded::<R::Dual>(1);
122
123 (
124 #dual_name {
125 sender: sender_dual,
126 },
127 #role_name {
128 sender: sender_normal,
129 },
130 )
131 }
132
133 #[doc(hidden)]
134 fn head_str() -> String {
135 String::from(stringify!(#dual_name))
136 }
137
138 #[doc(hidden)]
139 fn tail_str() -> String {
140 format!(
141 "{}<{}>",
142 <R as mpstthree::role::Role>::head_str(),
143 <R as mpstthree::role::Role>::tail_str()
144 )
145 }
146
147 #[doc(hidden)]
148 fn self_head_str(&self) -> String {
149 String::from(stringify!(#dual_name))
150 }
151
152 #[doc(hidden)]
153 fn self_tail_str(&self) -> String {
154 format!(
155 "{}<{}>",
156 <R as mpstthree::role::Role>::head_str(),
157 <R as mpstthree::role::Role>::tail_str()
158 )
159 }
160 }
161
162 impl<R: mpstthree::role::Role> #role_name<R> {
166 pub fn continuation(&self) -> R {
167 let (here, there) = R::new();
168 self.sender.send(there).unwrap_or(());
169 here
170 }
171 }
172
173 impl<R: mpstthree::role::Role> #dual_name<R> {
177 pub fn continuation(&self) -> R {
178 let (here, there) = R::new();
179 self.sender.send(there).unwrap_or(());
180 here
181 }
182 }
183 }
184 }
185}