@@ -10,7 +10,7 @@ use crate::{
1010 codegen:: {
1111 ItemStatus , StandaloneContainerAttributes , VersionDefinition ,
1212 changes:: Neighbors ,
13- container:: { CommonContainerData , Container , ContainerIdents , ContainerOptions } ,
13+ container:: { CommonContainerData , Container , ContainerIdents , ContainerOptions , Direction } ,
1414 item:: VersionedVariant ,
1515 } ,
1616} ;
@@ -122,9 +122,10 @@ impl Enum {
122122 }
123123 }
124124
125- /// Generates code for the `From<Version> for NextVersion` implementation.
126- pub fn generate_upgrade_from_impl (
125+ // TODO (@Techassi): Add doc comments
126+ pub fn generate_from_impl (
127127 & self ,
128+ direction : Direction ,
128129 version : & VersionDefinition ,
129130 next_version : Option < & VersionDefinition > ,
130131 add_attributes : bool ,
@@ -133,119 +134,69 @@ impl Enum {
133134 return None ;
134135 }
135136
136- match next_version {
137- Some ( next_version) => {
138- // TODO (@Techassi): Support generic types which have been removed in newer versions,
139- // but need to exist for older versions How do we represent that? Because the
140- // defined struct always represents the latest version. I guess we could generally
141- // advise against using generic types, but if you have to, avoid removing it in
142- // later versions.
143- let ( impl_generics, type_generics, where_clause) = self . generics . split_for_impl ( ) ;
144- let from_enum_ident = & self . common . idents . parameter ;
145- let enum_ident = & self . common . idents . original ;
146-
147- let for_module_ident = & next_version. idents . module ;
148- let from_module_ident = & version. idents . module ;
149-
150- let variants: TokenStream = self
151- . variants
152- . iter ( )
153- . filter_map ( |v| {
154- v. generate_for_upgrade_from_impl ( version, next_version, enum_ident)
155- } )
156- . collect ( ) ;
157-
158- // Include allow(deprecated) only when this or the next version is
159- // deprecated. Also include it, when a variant in this or the next
160- // version is deprecated.
161- let allow_attribute = ( version. deprecated . is_some ( )
162- || next_version. deprecated . is_some ( )
163- || self . is_any_variant_deprecated ( version)
164- || self . is_any_variant_deprecated ( next_version) )
165- . then_some ( quote ! { #[ allow( deprecated) ] } ) ;
166-
167- // Only add the #[automatically_derived] attribute only if this impl is used
168- // outside of a module (in standalone mode).
169- let automatically_derived = add_attributes
170- . not ( )
171- . then ( || quote ! { #[ automatically_derived] } ) ;
172-
173- Some ( quote ! {
174- #automatically_derived
175- #allow_attribute
176- impl #impl_generics :: std:: convert:: From <#from_module_ident:: #enum_ident #type_generics> for #for_module_ident:: #enum_ident #type_generics
177- #where_clause
178- {
179- fn from( #from_enum_ident: #from_module_ident:: #enum_ident #type_generics) -> Self {
180- match #from_enum_ident {
181- #variants
182- }
183- }
184- }
185- } )
186- }
187- None => None ,
188- }
189- }
190-
191- pub fn generate_downgrade_from_impl (
192- & self ,
193- version : & VersionDefinition ,
194- next_version : Option < & VersionDefinition > ,
195- add_attributes : bool ,
196- ) -> Option < TokenStream > {
197- if version. skip_from || self . common . options . skip_from {
198- return None ;
199- }
200-
201- match next_version {
202- Some ( next_version) => {
203- let ( impl_generics, type_generics, where_clause) = self . generics . split_for_impl ( ) ;
204- let from_enum_ident = & self . common . idents . parameter ;
205- let enum_ident = & self . common . idents . original ;
206-
207- let from_module_ident = & next_version. idents . module ;
208- let for_module_ident = & version. idents . module ;
209-
210- let variants: TokenStream = self
211- . variants
137+ next_version. map ( |next_version| {
138+ // TODO (@Techassi): Support generic types which have been removed in newer versions,
139+ // but need to exist for older versions How do we represent that? Because the
140+ // defined struct always represents the latest version. I guess we could generally
141+ // advise against using generic types, but if you have to, avoid removing it in
142+ // later versions.
143+ let ( impl_generics, type_generics, where_clause) = self . generics . split_for_impl ( ) ;
144+ let from_enum_ident = & self . common . idents . parameter ;
145+ let enum_ident = & self . common . idents . original ;
146+
147+ // Include allow(deprecated) only when this or the next version is
148+ // deprecated. Also include it, when a variant in this or the next
149+ // version is deprecated.
150+ let allow_attribute = ( version. deprecated . is_some ( )
151+ || next_version. deprecated . is_some ( )
152+ || self . is_any_variant_deprecated ( version)
153+ || self . is_any_variant_deprecated ( next_version) )
154+ . then_some ( quote ! { #[ allow( deprecated) ] } ) ;
155+
156+ // Only add the #[automatically_derived] attribute only if this impl is used
157+ // outside of a module (in standalone mode).
158+ let automatically_derived = add_attributes
159+ . not ( )
160+ . then ( || quote ! { #[ automatically_derived] } ) ;
161+
162+ let variants = |direction : Direction | -> TokenStream {
163+ self . variants
212164 . iter ( )
213165 . filter_map ( |v| {
214- v. generate_for_downgrade_from_impl ( version, next_version, enum_ident)
166+ v. generate_for_from_impl ( direction , version, next_version, enum_ident)
215167 } )
216- . collect ( ) ;
217-
218- // Include allow(deprecated) only when this or the next version is
219- // deprecated. Also include it, when a variant in this or the next
220- // version is deprecated.
221- let allow_attribute = ( version . deprecated . is_some ( )
222- || next_version . deprecated . is_some ( )
223- || self . is_any_variant_deprecated ( version )
224- || self . is_any_variant_deprecated ( next_version ) )
225- . then_some ( quote ! { # [ allow ( deprecated ) ] } ) ;
226-
227- // Only add the #[automatically_derived] attribute only if this impl is used
228- // outside of a module (in standalone mode).
229- let automatically_derived = add_attributes
230- . not ( )
231- . then ( || quote ! { # [ automatically_derived ] } ) ;
232-
233- Some ( quote ! {
234- #automatically_derived
235- #allow_attribute
236- impl #impl_generics :: std :: convert :: From <#from_module_ident :: #enum_ident #type_generics> for #for_module_ident :: #enum_ident #type_generics
237- #where_clause
238- {
239- fn from ( #from_enum_ident : #from_module_ident :: #enum_ident #type_generics ) -> Self {
240- match #from_enum_ident {
241- #variants
242- }
168+ . collect ( )
169+ } ;
170+
171+ let ( variants , for_module_ident , from_module_ident ) = match direction {
172+ Direction :: Upgrade => {
173+ let for_module_ident = & next_version . idents . module ;
174+ let from_module_ident = & version . idents . module ;
175+
176+ ( variants ( Direction :: Upgrade ) , for_module_ident , from_module_ident )
177+ } ,
178+ Direction :: Downgrade => {
179+ let for_module_ident = & version . idents . module ;
180+ let from_module_ident = & next_version . idents . module ;
181+
182+ ( variants ( Direction :: Downgrade ) , for_module_ident , from_module_ident )
183+ } ,
184+ } ;
185+
186+ quote ! {
187+ #automatically_derived
188+ #allow_attribute
189+ impl #impl_generics :: std :: convert :: From <#from_module_ident :: #enum_ident #type_generics> for #for_module_ident :: #enum_ident #type_generics
190+ #where_clause
191+ {
192+ fn from ( #from_enum_ident : #from_module_ident :: #enum_ident #type_generics ) -> Self {
193+ match #from_enum_ident {
194+ #variants
243195 }
244196 }
245- } )
197+ }
246198 }
247- None => None ,
248- }
199+ } )
249200 }
250201
251202 /// Returns whether any variant is deprecated in the provided `version`.
0 commit comments