@@ -2,7 +2,7 @@ use std::ops::{Deref, DerefMut};
22
33use darling:: FromVariant ;
44use proc_macro2:: { Span , TokenStream } ;
5- use quote:: quote;
5+ use quote:: { format_ident , quote} ;
66use syn:: { token:: Not , Ident , Type , TypeNever , Variant } ;
77
88use crate :: {
@@ -104,6 +104,7 @@ impl VersionedVariant {
104104 container_version : & ContainerVersion ,
105105 ) -> Option < TokenStream > {
106106 let original_attributes = & self . original_attributes ;
107+ let fields = & self . inner . fields ;
107108
108109 match & self . chain {
109110 // NOTE (@Techassi): https://rust-lang.github.io/rust-clippy/master/index.html#/expect_fun_call
@@ -115,11 +116,11 @@ impl VersionedVariant {
115116 } ) {
116117 ItemStatus :: Addition { ident, .. } => Some ( quote ! {
117118 #( #original_attributes) *
118- #ident,
119+ #ident #fields ,
119120 } ) ,
120121 ItemStatus :: Change { to_ident, .. } => Some ( quote ! {
121122 #( #original_attributes) *
122- #to_ident,
123+ #to_ident #fields ,
123124 } ) ,
124125 ItemStatus :: Deprecation { ident, note, .. } => {
125126 // FIXME (@Techassi): Emitting the deprecated attribute
@@ -139,7 +140,7 @@ impl VersionedVariant {
139140 Some ( quote ! {
140141 #( #original_attributes) *
141142 #deprecated_attr
142- #ident,
143+ #ident #fields ,
143144 } )
144145 }
145146 ItemStatus :: NoChange {
@@ -154,7 +155,7 @@ impl VersionedVariant {
154155 Some ( quote ! {
155156 #( #original_attributes) *
156157 #deprecated_attr
157- #ident,
158+ #ident #fields ,
158159 } )
159160 }
160161 ItemStatus :: NotPresent => None ,
@@ -163,11 +164,11 @@ impl VersionedVariant {
163164 // If there is no chain of variant actions, the variant is not
164165 // versioned and code generation is straight forward.
165166 // Unversioned variants are always included in versioned enums.
166- let variant_ident = & self . inner . ident ;
167+ let ident = & self . inner . ident ;
167168
168169 Some ( quote ! {
169170 #( #original_attributes) *
170- #variant_ident ,
171+ #ident #fields ,
171172 } )
172173 }
173174 }
@@ -182,6 +183,38 @@ impl VersionedVariant {
182183 next_version : & ContainerVersion ,
183184 enum_ident : & Ident ,
184185 ) -> 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+
185218 match & self . chain {
186219 Some ( chain) => match (
187220 chain. get_expect ( & version. inner ) ,
@@ -197,15 +230,15 @@ impl VersionedVariant {
197230 . expect ( "internal error: next variant must have a name" ) ;
198231
199232 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 ,
201234 }
202235 }
203236 } ,
204237 None => {
205238 let variant_ident = & self . inner . ident ;
206239
207240 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 ,
209242 }
210243 }
211244 }
0 commit comments