@@ -2,7 +2,7 @@ use std::ops::{Deref, DerefMut};
2
2
3
3
use darling:: FromVariant ;
4
4
use proc_macro2:: { Span , TokenStream } ;
5
- use quote:: quote;
5
+ use quote:: { format_ident , quote} ;
6
6
use syn:: { token:: Not , Ident , Type , TypeNever , Variant } ;
7
7
8
8
use crate :: {
@@ -104,6 +104,7 @@ impl VersionedVariant {
104
104
container_version : & ContainerVersion ,
105
105
) -> Option < TokenStream > {
106
106
let original_attributes = & self . original_attributes ;
107
+ let fields = & self . inner . fields ;
107
108
108
109
match & self . chain {
109
110
// NOTE (@Techassi): https://rust-lang.github.io/rust-clippy/master/index.html#/expect_fun_call
@@ -115,11 +116,11 @@ impl VersionedVariant {
115
116
} ) {
116
117
ItemStatus :: Addition { ident, .. } => Some ( quote ! {
117
118
#( #original_attributes) *
118
- #ident,
119
+ #ident #fields ,
119
120
} ) ,
120
121
ItemStatus :: Change { to_ident, .. } => Some ( quote ! {
121
122
#( #original_attributes) *
122
- #to_ident,
123
+ #to_ident #fields ,
123
124
} ) ,
124
125
ItemStatus :: Deprecation { ident, note, .. } => {
125
126
// FIXME (@Techassi): Emitting the deprecated attribute
@@ -139,7 +140,7 @@ impl VersionedVariant {
139
140
Some ( quote ! {
140
141
#( #original_attributes) *
141
142
#deprecated_attr
142
- #ident,
143
+ #ident #fields ,
143
144
} )
144
145
}
145
146
ItemStatus :: NoChange {
@@ -154,7 +155,7 @@ impl VersionedVariant {
154
155
Some ( quote ! {
155
156
#( #original_attributes) *
156
157
#deprecated_attr
157
- #ident,
158
+ #ident #fields ,
158
159
} )
159
160
}
160
161
ItemStatus :: NotPresent => None ,
@@ -163,11 +164,11 @@ impl VersionedVariant {
163
164
// If there is no chain of variant actions, the variant is not
164
165
// versioned and code generation is straight forward.
165
166
// Unversioned variants are always included in versioned enums.
166
- let variant_ident = & self . inner . ident ;
167
+ let ident = & self . inner . ident ;
167
168
168
169
Some ( quote ! {
169
170
#( #original_attributes) *
170
- #variant_ident ,
171
+ #ident #fields ,
171
172
} )
172
173
}
173
174
}
@@ -182,6 +183,38 @@ impl VersionedVariant {
182
183
next_version : & ContainerVersion ,
183
184
enum_ident : & Ident ,
184
185
) -> TokenStream {
186
+ let variant_data = match & self . inner . fields {
187
+ syn:: Fields :: Named ( fields_named) => {
188
+ let field_names = fields_named
189
+ . named
190
+ . iter ( )
191
+ . map ( |field| {
192
+ field
193
+ . ident
194
+ . as_ref ( )
195
+ . expect ( "named fields always have an ident" )
196
+ . clone ( )
197
+ } )
198
+ . collect :: < Vec < _ > > ( ) ;
199
+
200
+ let tokens = quote ! { { #( #field_names) , * } } ;
201
+ tokens
202
+ }
203
+ syn:: Fields :: Unnamed ( fields_unnamed) => {
204
+ let field_names = fields_unnamed
205
+ . unnamed
206
+ . iter ( )
207
+ . enumerate ( )
208
+ . map ( |( index, _) | format_ident ! ( "__sv_{index}" ) )
209
+ . collect :: < Vec < _ > > ( ) ;
210
+
211
+ let tokens = quote ! { ( #( #field_names) , * ) } ;
212
+ tokens
213
+ }
214
+
215
+ syn:: Fields :: Unit => TokenStream :: new ( ) ,
216
+ } ;
217
+
185
218
match & self . chain {
186
219
Some ( chain) => match (
187
220
chain. get_expect ( & version. inner ) ,
@@ -197,15 +230,15 @@ impl VersionedVariant {
197
230
. expect ( "internal error: next variant must have a name" ) ;
198
231
199
232
quote ! {
200
- #module_name:: #enum_ident:: #old_variant_ident => #next_module_name:: #enum_ident:: #next_variant_ident,
233
+ #module_name:: #enum_ident:: #old_variant_ident #variant_data => #next_module_name:: #enum_ident:: #next_variant_ident #variant_data ,
201
234
}
202
235
}
203
236
} ,
204
237
None => {
205
238
let variant_ident = & self . inner . ident ;
206
239
207
240
quote ! {
208
- #module_name:: #enum_ident:: #variant_ident => #next_module_name:: #enum_ident:: #variant_ident,
241
+ #module_name:: #enum_ident:: #variant_ident #variant_data => #next_module_name:: #enum_ident:: #variant_ident #variant_data ,
209
242
}
210
243
}
211
244
}
0 commit comments