1
1
use darling:: { Result , util:: IdentString } ;
2
2
use proc_macro2:: { Span , TokenStream } ;
3
- use quote:: quote;
3
+ use quote:: { format_ident , quote} ;
4
4
use syn:: { Attribute , Ident , ItemEnum , ItemStruct , Visibility } ;
5
5
6
- use super :: flux_converter:: { generate_kubernetes_conversion, generate_kubernetes_conversion_tests} ;
7
6
use crate :: {
8
7
attrs:: container:: { StandaloneContainerAttributes , k8s:: KubernetesArguments } ,
9
8
codegen:: {
10
- VersionDefinition ,
9
+ KubernetesTokens , VersionDefinition ,
11
10
container:: { r#enum:: Enum , r#struct:: Struct } ,
12
11
} ,
13
12
utils:: ContainerIdentExt ,
@@ -81,84 +80,25 @@ impl Container {
81
80
}
82
81
}
83
82
84
- /// Generates Kubernetes specific code snippets.
85
- ///
86
- /// This function returns three values:
87
- ///
88
- /// - an enum variant ident,
89
- /// - an enum variant display string,
90
- /// - and a `CustomResource::crd()` call
91
- ///
92
- /// This function only returns `Some` if it is a struct. Enums cannot be used to define
93
- /// Kubernetes custom resources.
94
- pub fn generate_kubernetes_item (
95
- & self ,
96
- version : & VersionDefinition ,
97
- ) -> Option < ( IdentString , String , TokenStream ) > {
98
- match self {
99
- Container :: Struct ( s) => s. generate_kubernetes_item ( version) ,
100
- Container :: Enum ( _) => None ,
101
- }
102
- }
103
-
104
- /// Generates Kubernetes specific code to merge two CRDs or convert between different versions.
105
- ///
106
- /// This function only returns `Some` if it is a struct. Enums cannot be used to define
107
- /// Kubernetes custom resources.
108
83
pub fn generate_kubernetes_code (
109
84
& self ,
110
- enum_variant_idents : & [ IdentString ] ,
111
- enum_variant_strings : & [ String ] ,
112
- fn_calls : & [ TokenStream ] ,
85
+ versions : & [ VersionDefinition ] ,
86
+ tokens : & KubernetesTokens ,
113
87
vis : & Visibility ,
114
88
is_nested : bool ,
115
89
) -> Option < TokenStream > {
116
- let Container :: Struct ( s) = self else {
117
- return None ;
118
- } ;
119
- let kubernetes_arguments = s. common . options . kubernetes_arguments . as_ref ( ) ?;
120
-
121
- let mut tokens = TokenStream :: new ( ) ;
122
-
123
- if !kubernetes_arguments
124
- . skip
125
- . as_ref ( )
126
- . is_some_and ( |s| s. merged_crd . is_present ( ) )
127
- {
128
- tokens. extend ( s. generate_kubernetes_merge_crds (
129
- enum_variant_idents,
130
- enum_variant_strings,
131
- fn_calls,
132
- vis,
133
- is_nested,
134
- ) ) ;
135
-
136
- tokens. extend ( s. generate_from_functions (
137
- enum_variant_idents,
138
- enum_variant_strings,
139
- is_nested,
140
- ) ) ;
141
- tokens. extend ( generate_kubernetes_conversion (
142
- & s. common . idents . kubernetes ,
143
- & s. common . idents . original ,
144
- enum_variant_idents,
145
- enum_variant_strings,
146
- kubernetes_arguments,
147
- ) ) ;
148
- tokens. extend ( generate_kubernetes_conversion_tests (
149
- & s. common . idents . kubernetes ,
150
- & s. common . idents . original ,
151
- enum_variant_strings,
152
- kubernetes_arguments,
153
- ) ) ;
90
+ match self {
91
+ Container :: Struct ( s) => s. generate_kubernetes_code ( versions, tokens, vis, is_nested) ,
92
+ Container :: Enum ( _) => None ,
154
93
}
155
-
156
- Some ( tokens)
157
94
}
158
95
159
- pub fn generate_kubernetes_status_struct ( & self ) -> Option < TokenStream > {
96
+ pub fn generate_kubernetes_version_items (
97
+ & self ,
98
+ version : & VersionDefinition ,
99
+ ) -> Option < ( TokenStream , IdentString , TokenStream , String ) > {
160
100
match self {
161
- Container :: Struct ( s) => s. generate_kubernetes_status_struct ( ) ,
101
+ Container :: Struct ( s) => s. generate_kubernetes_version_items ( version ) ,
162
102
Container :: Enum ( _) => None ,
163
103
}
164
104
}
@@ -222,16 +162,14 @@ impl StandaloneContainer {
222
162
pub fn generate_tokens ( & self ) -> TokenStream {
223
163
let vis = & self . vis ;
224
164
165
+ let mut kubernetes_tokens = KubernetesTokens :: default ( ) ;
225
166
let mut tokens = TokenStream :: new ( ) ;
226
167
227
- let mut kubernetes_merge_crds_fn_calls = Vec :: new ( ) ;
228
- let mut kubernetes_enum_variant_idents = Vec :: new ( ) ;
229
- let mut kubernetes_enum_variant_strings = Vec :: new ( ) ;
230
-
231
168
let mut versions = self . versions . iter ( ) . peekable ( ) ;
232
169
233
170
while let Some ( version) = versions. next ( ) {
234
171
let container_definition = self . container . generate_definition ( version) ;
172
+ let module_ident = & version. idents . module ;
235
173
236
174
// NOTE (@Techassi): Using '.copied()' here does not copy or clone the data, but instead
237
175
// removes one level of indirection of the double reference '&&'.
@@ -253,22 +191,16 @@ impl StandaloneContainer {
253
191
. as_ref ( )
254
192
. map ( |note| quote ! { #[ deprecated = #note] } ) ;
255
193
256
- // Generate Kubernetes specific code which is placed outside of the container
257
- // definition.
258
- if let Some ( ( enum_variant_ident, enum_variant_string, fn_call) ) =
259
- self . container . generate_kubernetes_item ( version)
260
- {
261
- kubernetes_merge_crds_fn_calls. push ( fn_call) ;
262
- kubernetes_enum_variant_idents. push ( enum_variant_ident) ;
263
- kubernetes_enum_variant_strings. push ( enum_variant_string) ;
194
+ // Generate Kubernetes specific code (for a particular version) which is placed outside
195
+ // of the container definition.
196
+ if let Some ( items) = self . container . generate_kubernetes_version_items ( version) {
197
+ kubernetes_tokens. push ( items) ;
264
198
}
265
199
266
- let version_ident = & version. ident ;
267
-
268
200
tokens. extend ( quote ! {
269
201
#[ automatically_derived]
270
202
#deprecated_attribute
271
- #vis mod #version_ident {
203
+ #vis mod #module_ident {
272
204
use super :: * ;
273
205
#container_definition
274
206
}
@@ -278,49 +210,68 @@ impl StandaloneContainer {
278
210
} ) ;
279
211
}
280
212
213
+ // Finally add tokens outside of the container definitions
281
214
tokens. extend ( self . container . generate_kubernetes_code (
282
- & kubernetes_enum_variant_idents,
283
- & kubernetes_enum_variant_strings,
284
- & kubernetes_merge_crds_fn_calls,
215
+ & self . versions ,
216
+ & kubernetes_tokens,
285
217
vis,
286
218
false ,
287
219
) ) ;
288
220
289
- tokens. extend ( self . container . generate_kubernetes_status_struct ( ) ) ;
290
-
291
221
tokens
292
222
}
293
223
}
294
224
295
225
/// A collection of container idents used for different purposes.
296
226
#[ derive( Debug ) ]
297
227
pub struct ContainerIdents {
298
- /// The ident used in the context of Kubernetes specific code. This ident
299
- /// removes the 'Spec' suffix present in the definition container .
228
+ /// This ident removes the 'Spec' suffix present in the definition container.
229
+ /// This ident is only used in the context of Kubernetes specific code .
300
230
pub kubernetes : IdentString ,
301
231
232
+ /// This ident uses the base Kubernetes ident to construct an appropriate ident
233
+ /// for auto-generated status structs. This ident is only used in the context of
234
+ /// Kubernetes specific code.
235
+ pub kubernetes_status : IdentString ,
236
+
237
+ /// This ident uses the base Kubernetes ident to construct an appropriate ident
238
+ /// for auto-generated version enums. This enum is used to select the stored
239
+ /// api version when merging CRDs. This ident is only used in the context of
240
+ /// Kubernetes specific code.
241
+ pub kubernetes_version : IdentString ,
242
+
243
+ // TODO (@Techassi): Add comment
244
+ pub kubernetes_parameter : IdentString ,
245
+
302
246
/// The original ident, or name, of the versioned container.
303
247
pub original : IdentString ,
304
248
305
- /// The ident used in the [`From`] impl .
306
- pub from : IdentString ,
249
+ /// The ident used as a parameter .
250
+ pub parameter : IdentString ,
307
251
}
308
252
309
253
impl ContainerIdents {
310
254
pub fn from ( ident : Ident , kubernetes_arguments : Option < & KubernetesArguments > ) -> Self {
311
- let kubernetes = kubernetes_arguments. map_or_else (
312
- || ident. as_cleaned_kubernetes_ident ( ) ,
313
- |options| {
314
- options. kind . as_ref ( ) . map_or_else (
315
- || ident. as_cleaned_kubernetes_ident ( ) ,
316
- |kind| IdentString :: from ( Ident :: new ( kind, Span :: call_site ( ) ) ) ,
317
- )
255
+ let kubernetes = match kubernetes_arguments {
256
+ Some ( args) => match & args. kind {
257
+ Some ( kind) => IdentString :: from ( Ident :: new ( kind, Span :: call_site ( ) ) ) ,
258
+ None => ident. as_cleaned_kubernetes_ident ( ) ,
318
259
} ,
319
- ) ;
260
+ None => ident. as_cleaned_kubernetes_ident ( ) ,
261
+ } ;
262
+
263
+ let kubernetes_status =
264
+ IdentString :: from ( format_ident ! ( "{kubernetes}StatusWithChangedValues" ) ) ;
265
+
266
+ let kubernetes_version = IdentString :: from ( format_ident ! ( "{kubernetes}Version" ) ) ;
267
+ let kubernetes_parameter = kubernetes. as_parameter_ident ( ) ;
320
268
321
269
Self {
322
- from : ident. as_from_impl_ident ( ) ,
270
+ parameter : ident. as_parameter_ident ( ) ,
323
271
original : ident. into ( ) ,
272
+ kubernetes_parameter,
273
+ kubernetes_version,
274
+ kubernetes_status,
324
275
kubernetes,
325
276
}
326
277
}
0 commit comments