1use {
4 proc_macro2::TokenStream,
5 quote::{quote_spanned, ToTokens},
6 std::{fmt, rc::Rc},
7 syn::{Path, Type},
8};
9
10use crate::Spanned;
11
12#[derive(Clone, Debug)]
20pub enum Target {
21 Done,
23 Recv(Type, Rc<Spanned<Target>>),
25 Send(Type, Rc<Spanned<Target>>),
27 Choose(Vec<Spanned<Target>>),
29 Offer(Vec<Spanned<Target>>),
31 Loop(Rc<Spanned<Target>>),
33 Continue(usize),
35 Split {
37 tx_only: Rc<Spanned<Target>>,
39 rx_only: Rc<Spanned<Target>>,
41 cont: Rc<Spanned<Target>>,
43 },
44 Call(Rc<Spanned<Target>>, Rc<Spanned<Target>>),
46 Then(Rc<Spanned<Target>>, Rc<Spanned<Target>>),
48 Type(Type),
50}
51
52impl fmt::Display for Target {
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 use Target::*;
55 match self {
56 Done => write!(f, "Done")?,
57 Recv(t, s) => write!(f, "Recv<{}, {}>", t.to_token_stream(), s)?,
58 Send(t, s) => write!(f, "Send<{}, {}>", t.to_token_stream(), s)?,
59 Loop(s) => write!(f, "Loop<{}>", s)?,
60 Split {
61 tx_only: s,
62 rx_only: p,
63 cont: q,
64 } => write!(f, "Split<{}, {}, {}>", s, p, q)?,
65 Call(s, p) => write!(f, "Call<{}, {}>", s, p)?,
66 Then(s, p) => write!(f, "<{} as Then<{}>>::Combined", s, p)?,
67 Choose(cs) => {
68 let count = cs.len();
69 write!(f, "Choose<(")?;
70 for (i, c) in cs.iter().enumerate() {
71 write!(f, "{}", c)?;
72 if i + 1 < count {
73 write!(f, ", ")?;
74 }
75 }
76 if count == 1 {
77 write!(f, ",")?;
78 }
79 write!(f, ")>")?;
80 }
81 Offer(cs) => {
82 let count = cs.len();
83 write!(f, "Offer<(")?;
84 for (i, c) in cs.iter().enumerate() {
85 write!(f, "{}", c)?;
86 if i + 1 < count {
87 write!(f, ", ")?;
88 }
89 }
90 if count == 1 {
91 write!(f, ",")?;
92 }
93 write!(f, ")>")?;
94 }
95 Continue(n) => {
96 write!(f, "Continue<{}>", n)?;
97 }
98 Type(s) => write!(f, "{}", s.to_token_stream())?,
99 }
100 Ok(())
101 }
102}
103
104impl Spanned<Target> {
105 pub fn to_token_stream_with_crate_name(&self, dialectic_crate: &Path) -> TokenStream {
108 let mut tokens = TokenStream::new();
109 self.to_tokens_with_crate_name(dialectic_crate, &mut tokens);
110 tokens
111 }
112
113 pub fn to_tokens_with_crate_name(&self, dialectic_crate: &Path, tokens: &mut TokenStream) {
116 use Target::*;
117
118 let span = self.span;
121
122 match &self.inner {
123 Done => quote_spanned! {span=> #dialectic_crate::types::Done }.to_tokens(tokens),
124 Recv(t, s) => {
125 let s = s.to_token_stream_with_crate_name(dialectic_crate);
126 quote_spanned!(span=> #dialectic_crate::types::Recv<#t, #s>).to_tokens(tokens);
127 }
128 Send(t, s) => {
129 let s = s.to_token_stream_with_crate_name(dialectic_crate);
130 quote_spanned!(span=> #dialectic_crate::types::Send<#t, #s>).to_tokens(tokens);
131 }
132 Loop(s) => {
133 let s = s.to_token_stream_with_crate_name(dialectic_crate);
134 quote_spanned!(span=> #dialectic_crate::types::Loop<#s>).to_tokens(tokens);
135 }
136 Split {
137 tx_only: s,
138 rx_only: p,
139 cont: q,
140 } => {
141 let s = s.to_token_stream_with_crate_name(dialectic_crate);
142 let p = p.to_token_stream_with_crate_name(dialectic_crate);
143 let q = q.to_token_stream_with_crate_name(dialectic_crate);
144 quote_spanned!(span=> #dialectic_crate::types::Split<#s, #p, #q>).to_tokens(tokens);
145 }
146 Call(s, p) => {
147 let s = s.to_token_stream_with_crate_name(dialectic_crate);
148 let p = p.to_token_stream_with_crate_name(dialectic_crate);
149 quote_spanned!(span=> #dialectic_crate::types::Call<#s, #p>).to_tokens(tokens);
150 }
151 Then(s, p) => {
152 let s = s.to_token_stream_with_crate_name(dialectic_crate);
153 let p = p.to_token_stream_with_crate_name(dialectic_crate);
154 quote_spanned!(span=> <#s as #dialectic_crate::types::Then<#p>>::Combined)
155 .to_tokens(tokens);
156 }
157 Choose(cs) => {
158 let cs = cs
159 .iter()
160 .map(|c| c.to_token_stream_with_crate_name(dialectic_crate));
161 quote_spanned!(span=> #dialectic_crate::types::Choose<(#(#cs,)*)>).to_tokens(tokens)
162 }
163 Offer(cs) => {
164 let cs = cs
165 .iter()
166 .map(|c| c.to_token_stream_with_crate_name(dialectic_crate));
167 quote_spanned!(span=> #dialectic_crate::types::Offer<(#(#cs,)*)>).to_tokens(tokens)
168 }
169 Continue(n) => {
170 quote_spanned!(span=> #dialectic_crate::types::Continue<#n>).to_tokens(tokens)
171 }
172 Type(s) => quote_spanned!(span=> #s).to_tokens(tokens),
173 }
174 }
175}
176
177impl ToTokens for Spanned<Target> {
178 fn to_tokens(&self, tokens: &mut TokenStream) {
179 self.to_tokens_with_crate_name(&crate::dialectic_path(), tokens);
180 }
181}