@@ -10,14 +10,20 @@ use crate::{
10
10
codegen:: {
11
11
chain:: Neighbors ,
12
12
common:: {
13
- Container , ContainerInput , Item , ItemStatus , VersionDefinition , VersionedContainer ,
13
+ generate_module, Container , ContainerInput , Item , ItemStatus , VersionDefinition ,
14
+ VersionedContainer ,
14
15
} ,
15
16
venum:: variant:: VersionedVariant ,
16
17
} ,
17
18
} ;
18
19
19
20
pub ( crate ) mod variant;
20
21
22
+ pub ( crate ) struct GenerateVersionTokens {
23
+ from_impl : Option < TokenStream > ,
24
+ enum_definition : TokenStream ,
25
+ }
26
+
21
27
/// Stores individual versions of a single enum. Each version tracks variant
22
28
/// actions, which describe if the variant was added, renamed or deprecated in
23
29
/// that version. Variants which are not versioned, are included in every
@@ -79,14 +85,22 @@ impl Container<Punctuated<Variant, Comma>, VersionedVariant> for VersionedEnum {
79
85
}
80
86
81
87
fn generate_standalone_tokens ( & self ) -> TokenStream {
82
- let mut token_stream = TokenStream :: new ( ) ;
88
+ let mut tokens = TokenStream :: new ( ) ;
83
89
let mut versions = self . versions . iter ( ) . peekable ( ) ;
84
90
85
91
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) ;
87
101
}
88
102
89
- token_stream
103
+ tokens
90
104
}
91
105
92
106
fn generate_nested_tokens ( & self ) -> TokenStream {
@@ -99,51 +113,37 @@ impl VersionedEnum {
99
113
& self ,
100
114
version : & VersionDefinition ,
101
115
next_version : Option < & VersionDefinition > ,
102
- ) -> TokenStream {
103
- let mut token_stream = TokenStream :: new ( ) ;
116
+ ) -> GenerateVersionTokens {
117
+ let mut enum_definition = TokenStream :: new ( ) ;
104
118
105
119
let original_attributes = & self . original_attributes ;
106
120
let enum_name = & self . idents . original ;
107
- let visibility = & self . visibility ;
108
121
109
122
// Generate variants of the enum for `version`.
110
123
let variants = self . generate_enum_variants ( version) ;
111
124
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
-
123
125
// Generate doc comments for the container (enum)
124
126
let version_specific_docs = self . generate_enum_docs ( version) ;
125
127
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
138
134
}
139
135
} ) ;
140
136
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
+ } ;
145
142
146
- token_stream
143
+ GenerateVersionTokens {
144
+ enum_definition,
145
+ from_impl,
146
+ }
147
147
}
148
148
149
149
/// Generates version specific doc comments for the enum.
@@ -180,7 +180,7 @@ impl VersionedEnum {
180
180
& self ,
181
181
version : & VersionDefinition ,
182
182
next_version : Option < & VersionDefinition > ,
183
- ) -> TokenStream {
183
+ ) -> Option < TokenStream > {
184
184
if let Some ( next_version) = next_version {
185
185
let next_module_name = & next_version. ident ;
186
186
let module_name = & version. ident ;
@@ -209,20 +209,20 @@ impl VersionedEnum {
209
209
|| self . is_any_variant_deprecated ( next_version) )
210
210
. then_some ( quote ! { #[ allow( deprecated) ] } ) ;
211
211
212
- return quote ! {
212
+ return Some ( quote ! {
213
213
#[ automatically_derived]
214
214
#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 {
216
216
fn from( #from_ident: #module_name:: #enum_ident) -> Self {
217
217
match #from_ident {
218
218
#variants
219
219
}
220
220
}
221
221
}
222
- } ;
222
+ } ) ;
223
223
}
224
224
225
- quote ! { }
225
+ None
226
226
}
227
227
228
228
/// Returns whether any field is deprecated in the provided
0 commit comments