@@ -4,7 +4,9 @@ use darling::{FromVariant, Result, util::IdentString};
44use k8s_version:: Version ;
55use proc_macro2:: { Span , TokenStream } ;
66use quote:: { format_ident, quote} ;
7- use syn:: { Attribute , Fields , Type , TypeNever , Variant , token:: Not } ;
7+ use syn:: {
8+ Attribute , Fields , FieldsNamed , FieldsUnnamed , Ident , Type , TypeNever , Variant , token:: Not ,
9+ } ;
810
911use crate :: {
1012 attrs:: item:: VariantAttributes ,
@@ -138,7 +140,8 @@ impl VersionedVariant {
138140 next_version : & VersionDefinition ,
139141 enum_ident : & IdentString ,
140142 ) -> Option < TokenStream > {
141- let variant_fields = self . fields_as_token_stream ( ) ;
143+ let from_fields = self . generate_from_fields ( ) ;
144+ let for_fields = self . generate_for_fields ( ) ;
142145
143146 match & self . changes {
144147 Some ( changes) => {
@@ -154,16 +157,15 @@ impl VersionedVariant {
154157 let next_variant_ident = next. get_ident ( ) ;
155158 let old_variant_ident = old. get_ident ( ) ;
156159
157- let old = quote ! {
158- #old_version_ident:: #enum_ident:: #old_variant_ident #variant_fields
159- } ;
160- let next = quote ! {
161- #next_version_ident:: #enum_ident:: #next_variant_ident #variant_fields
162- } ;
163-
164160 match direction {
165- Direction :: Upgrade => Some ( quote ! { #old => #next, } ) ,
166- Direction :: Downgrade => Some ( quote ! { #next => #old, } ) ,
161+ Direction :: Upgrade => Some ( quote ! {
162+ #old_version_ident:: #enum_ident:: #old_variant_ident #from_fields
163+ => #next_version_ident:: #enum_ident:: #next_variant_ident #for_fields,
164+ } ) ,
165+ Direction :: Downgrade => Some ( quote ! {
166+ #next_version_ident:: #enum_ident:: #next_variant_ident #from_fields
167+ => #old_version_ident:: #enum_ident:: #old_variant_ident #from_fields,
168+ } ) ,
167169 }
168170 }
169171 }
@@ -173,48 +175,67 @@ impl VersionedVariant {
173175 let old_version_ident = & version. idents . module ;
174176 let variant_ident = & * self . ident ;
175177
176- let old = quote ! {
177- #old_version_ident:: #enum_ident:: #variant_ident #variant_fields
178- } ;
179- let next = quote ! {
180- #next_version_ident:: #enum_ident:: #variant_ident #variant_fields
181- } ;
182-
183178 match direction {
184- Direction :: Upgrade => Some ( quote ! { #old => #next, } ) ,
185- Direction :: Downgrade => Some ( quote ! { #next => #old, } ) ,
179+ Direction :: Upgrade => Some ( quote ! {
180+ #old_version_ident:: #enum_ident:: #variant_ident #from_fields
181+ => #next_version_ident:: #enum_ident:: #variant_ident #for_fields,
182+ } ) ,
183+ Direction :: Downgrade => Some ( quote ! {
184+ #next_version_ident:: #enum_ident:: #variant_ident #from_fields
185+ => #old_version_ident:: #enum_ident:: #variant_ident #for_fields,
186+ } ) ,
186187 }
187188 }
188189 }
189190 }
190191
191- fn fields_as_token_stream ( & self ) -> Option < TokenStream > {
192+ fn generate_for_fields ( & self ) -> Option < TokenStream > {
192193 match & self . fields {
193194 Fields :: Named ( fields_named) => {
194- let fields: Vec < _ > = fields_named
195- . named
196- . iter ( )
197- . map ( |field| {
198- field
199- . ident
200- . as_ref ( )
201- . expect ( "named fields always have an ident" )
202- } )
203- . collect ( ) ;
195+ let fields = Self :: named_field_idents ( fields_named) ;
196+ Some ( quote ! { { # ( #fields : #fields . into ( ) , ) * } } )
197+ }
198+ Fields :: Unnamed ( fields_unnamed ) => {
199+ let fields = Self :: unnamed_field_ident ( fields_unnamed ) ;
200+ Some ( quote ! { ( # ( #fields . into ( ) ) * ) } )
201+ }
202+ Fields :: Unit => None ,
203+ }
204+ }
204205
205- Some ( quote ! { { #( #fields) , * } } )
206+ fn generate_from_fields ( & self ) -> Option < TokenStream > {
207+ match & self . fields {
208+ Fields :: Named ( fields_named) => {
209+ let fields = Self :: named_field_idents ( fields_named) ;
210+ Some ( quote ! { { #( #fields, ) * } } )
206211 }
207212 Fields :: Unnamed ( fields_unnamed) => {
208- let fields: Vec < _ > = fields_unnamed
209- . unnamed
210- . iter ( )
211- . enumerate ( )
212- . map ( |( index, _) | format_ident ! ( "__sv_{index}" ) )
213- . collect ( ) ;
214-
215- Some ( quote ! { ( #( #fields) , * ) } )
213+ let fields = Self :: unnamed_field_ident ( fields_unnamed) ;
214+ Some ( quote ! { ( #( #fields) * ) } )
216215 }
217216 Fields :: Unit => None ,
218217 }
219218 }
219+
220+ fn named_field_idents ( fields_named : & FieldsNamed ) -> Vec < & Ident > {
221+ fields_named
222+ . named
223+ . iter ( )
224+ . map ( |field| {
225+ field
226+ . ident
227+ . as_ref ( )
228+ . expect ( "named fields always have an ident" )
229+ } )
230+ . collect ( )
231+ }
232+
233+ fn unnamed_field_ident ( fields_unnamed : & FieldsUnnamed ) -> Vec < Ident > {
234+ fields_unnamed
235+ . unnamed
236+ . iter ( )
237+ . enumerate ( )
238+ . map ( |( index, _) | format_ident ! ( "__sv_{index}" ) )
239+ . collect ( )
240+ }
220241}
0 commit comments