@@ -10,14 +10,20 @@ use crate::{
1010 codegen:: {
1111 chain:: Neighbors ,
1212 common:: {
13- Container , ContainerInput , Item , ItemStatus , VersionDefinition , VersionedContainer ,
13+ generate_module, Container , ContainerInput , Item , ItemStatus , VersionDefinition ,
14+ VersionedContainer ,
1415 } ,
1516 venum:: variant:: VersionedVariant ,
1617 } ,
1718} ;
1819
1920pub ( crate ) mod variant;
2021
22+ pub ( crate ) struct GenerateVersionTokens {
23+ from_impl : Option < TokenStream > ,
24+ enum_definition : TokenStream ,
25+ }
26+
2127/// Stores individual versions of a single enum. Each version tracks variant
2228/// actions, which describe if the variant was added, renamed or deprecated in
2329/// that version. Variants which are not versioned, are included in every
@@ -79,14 +85,22 @@ impl Container<Punctuated<Variant, Comma>, VersionedVariant> for VersionedEnum {
7985 }
8086
8187 fn generate_standalone_tokens ( & self ) -> TokenStream {
82- let mut token_stream = TokenStream :: new ( ) ;
88+ let mut tokens = TokenStream :: new ( ) ;
8389 let mut versions = self . versions . iter ( ) . peekable ( ) ;
8490
8591 while let Some ( version) = versions. next ( ) {
86- token_stream. extend ( self . generate_version ( version, versions. peek ( ) . copied ( ) ) ) ;
92+ let GenerateVersionTokens {
93+ enum_definition,
94+ from_impl,
95+ } = self . generate_version ( version, versions. peek ( ) . copied ( ) ) ;
96+
97+ let module_definition = generate_module ( version, & self . visibility , enum_definition) ;
98+
99+ tokens. extend ( module_definition) ;
100+ tokens. extend ( from_impl) ;
87101 }
88102
89- token_stream
103+ tokens
90104 }
91105
92106 fn generate_nested_tokens ( & self ) -> TokenStream {
@@ -99,51 +113,37 @@ impl VersionedEnum {
99113 & self ,
100114 version : & VersionDefinition ,
101115 next_version : Option < & VersionDefinition > ,
102- ) -> TokenStream {
103- let mut token_stream = TokenStream :: new ( ) ;
116+ ) -> GenerateVersionTokens {
117+ let mut enum_definition = TokenStream :: new ( ) ;
104118
105119 let original_attributes = & self . original_attributes ;
106120 let enum_name = & self . idents . original ;
107- let visibility = & self . visibility ;
108121
109122 // Generate variants of the enum for `version`.
110123 let variants = self . generate_enum_variants ( version) ;
111124
112- // TODO (@Techassi): Make the generation of the module optional to
113- // enable the attribute macro to be applied to a module which
114- // generates versioned versions of all contained containers.
115-
116- let version_ident = & version. ident ;
117-
118- let deprecated_note = format ! ( "Version {version} is deprecated" , version = version_ident) ;
119- let deprecated_attr = version
120- . deprecated
121- . then_some ( quote ! { #[ deprecated = #deprecated_note] } ) ;
122-
123125 // Generate doc comments for the container (enum)
124126 let version_specific_docs = self . generate_enum_docs ( version) ;
125127
126- // Generate tokens for the module and the contained enum
127- token_stream. extend ( quote ! {
128- #[ automatically_derived]
129- #deprecated_attr
130- #visibility mod #version_ident {
131- use super :: * ;
132-
133- #version_specific_docs
134- #( #original_attributes) *
135- pub enum #enum_name {
136- #variants
137- }
128+ // Generate enum definition tokens
129+ enum_definition. extend ( quote ! {
130+ #version_specific_docs
131+ #( #original_attributes) *
132+ pub enum #enum_name {
133+ #variants
138134 }
139135 } ) ;
140136
141- // Generate the From impl between this `version` and the next one.
142- if !self . options . skip_from && !version. skip_from {
143- token_stream. extend ( self . generate_from_impl ( version, next_version) ) ;
144- }
137+ let from_impl = if !self . options . skip_from && !version. skip_from {
138+ self . generate_from_impl ( version, next_version)
139+ } else {
140+ None
141+ } ;
145142
146- token_stream
143+ GenerateVersionTokens {
144+ enum_definition,
145+ from_impl,
146+ }
147147 }
148148
149149 /// Generates version specific doc comments for the enum.
@@ -180,7 +180,7 @@ impl VersionedEnum {
180180 & self ,
181181 version : & VersionDefinition ,
182182 next_version : Option < & VersionDefinition > ,
183- ) -> TokenStream {
183+ ) -> Option < TokenStream > {
184184 if let Some ( next_version) = next_version {
185185 let next_module_name = & next_version. ident ;
186186 let module_name = & version. ident ;
@@ -209,20 +209,20 @@ impl VersionedEnum {
209209 || self . is_any_variant_deprecated ( next_version) )
210210 . then_some ( quote ! { #[ allow( deprecated) ] } ) ;
211211
212- return quote ! {
212+ return Some ( quote ! {
213213 #[ automatically_derived]
214214 #allow_attribute
215- impl From <#module_name:: #enum_ident> for #next_module_name:: #enum_ident {
215+ impl :: std :: convert :: From <#module_name:: #enum_ident> for #next_module_name:: #enum_ident {
216216 fn from( #from_ident: #module_name:: #enum_ident) -> Self {
217217 match #from_ident {
218218 #variants
219219 }
220220 }
221221 }
222- } ;
222+ } ) ;
223223 }
224224
225- quote ! { }
225+ None
226226 }
227227
228228 /// Returns whether any field is deprecated in the provided
0 commit comments