1
1
use darling:: { util:: SpannedValue , Error , FromMeta } ;
2
2
use k8s_version:: Version ;
3
3
use proc_macro2:: Span ;
4
- use syn:: { spanned:: Spanned , Attribute , Ident , Path } ;
4
+ use syn:: { spanned:: Spanned , Attribute , Ident , Path , Type } ;
5
5
6
6
use crate :: {
7
7
attrs:: common:: ContainerAttributes ,
@@ -55,14 +55,14 @@ where
55
55
}
56
56
}
57
57
58
- for rename in & * self . common_attributes ( ) . renames {
58
+ for change in & * self . common_attributes ( ) . changes {
59
59
if !container_attrs
60
60
. versions
61
61
. iter ( )
62
- . any ( |v| v. name == * rename . since )
62
+ . any ( |v| v. name == * change . since )
63
63
{
64
64
errors. push (
65
- Error :: custom ( "variant action `renamed ` uses version which was not declared via #[versioned(version)]" )
65
+ Error :: custom ( "variant action `changed ` uses version which was not declared via #[versioned(version)]" )
66
66
. with_span ( item)
67
67
) ;
68
68
}
@@ -97,15 +97,20 @@ pub(crate) enum ItemType {
97
97
Variant ,
98
98
}
99
99
100
+ // TODO (@Techassi): Shower thought: Track actions as a Vec of an ActionAttribute
101
+ // enum and implement Ord on it. This would allow us to order the items by type
102
+ // of action (added < changed < deprecated) as well as sort changed action to
103
+ // each other by specified version (which already implements Ord)
104
+
100
105
/// These attributes are meant to be used in super structs, which add
101
106
/// [`Field`](syn::Field) or [`Variant`](syn::Variant) specific attributes via
102
107
/// darling's flatten feature. This struct only provides shared attributes.
103
108
///
104
109
/// ### Shared Item Rules
105
110
///
106
111
/// - An item can only ever be added once at most. An item not marked as 'added'
107
- /// is part of the container in every version until renamed or deprecated.
108
- /// - An item can be renamed many times. That's why renames are stored in a
112
+ /// is part of the container in every version until changed or deprecated.
113
+ /// - An item can be changed many times. That's why changes are stored in a
109
114
/// [`Vec`].
110
115
/// - An item can only be deprecated once. A field or variant not marked as
111
116
/// 'deprecated' will be included up until the latest version.
@@ -115,10 +120,10 @@ pub(crate) struct ItemAttributes {
115
120
/// only be present at most once.
116
121
pub ( crate ) added : Option < AddedAttributes > ,
117
122
118
- /// This parses the `renamed ` attribute on items (fields or variants). It
123
+ /// This parses the `changed ` attribute on items (fields or variants). It
119
124
/// can be present 0..n times.
120
- #[ darling( multiple, rename = "renamed " ) ]
121
- pub ( crate ) renames : Vec < RenamedAttributes > ,
125
+ #[ darling( multiple, rename = "changed " ) ]
126
+ pub ( crate ) changes : Vec < ChangedAttributes > ,
122
127
123
128
/// This parses the `deprecated` attribute on items (fields or variants). It
124
129
/// can only be present at most once.
@@ -138,20 +143,6 @@ impl ItemAttributes {
138
143
139
144
let mut errors = Error :: accumulator ( ) ;
140
145
141
- // TODO (@Techassi): Make the field or variant 'note' optional, because
142
- // in the future, the macro will generate parts of the deprecation note
143
- // automatically. The user-provided note will then be appended to the
144
- // auto-generated one.
145
-
146
- if let Some ( deprecated) = & self . deprecated {
147
- if deprecated. note . is_empty ( ) {
148
- errors. push (
149
- Error :: custom ( "deprecation note must not be empty" )
150
- . with_span ( & deprecated. note . span ( ) ) ,
151
- ) ;
152
- }
153
- }
154
-
155
146
// Semantic validation
156
147
errors. handle ( self . validate_action_combinations ( item_ident, item_type) ) ;
157
148
errors. handle ( self . validate_action_order ( item_ident, item_type) ) ;
@@ -175,34 +166,34 @@ impl ItemAttributes {
175
166
/// cannot be marked as added in a particular version and then marked as
176
167
/// deprecated immediately after. Fields and variants must be included for
177
168
/// at least one version before being marked deprecated.
178
- /// - `added` and `renamed ` using the same version: The same reasoning from
169
+ /// - `added` and `changed ` using the same version: The same reasoning from
179
170
/// above applies here as well. Fields and variants must be included for
180
- /// at least one version before being renamed .
181
- /// - `renamed ` and `deprecated` using the same version: Again, the same
171
+ /// at least one version before being changed .
172
+ /// - `changed ` and `deprecated` using the same version: Again, the same
182
173
/// rules from above apply here as well.
183
174
fn validate_action_combinations (
184
175
& self ,
185
176
item_ident : & Ident ,
186
177
item_type : & ItemType ,
187
178
) -> Result < ( ) , Error > {
188
- match ( & self . added , & self . renames , & self . deprecated ) {
179
+ match ( & self . added , & self . changes , & self . deprecated ) {
189
180
( Some ( added) , _, Some ( deprecated) ) if * added. since == * deprecated. since => {
190
181
Err ( Error :: custom ( format ! (
191
182
"{item_type} cannot be marked as `added` and `deprecated` in the same version"
192
183
) )
193
184
. with_span ( item_ident) )
194
185
}
195
- ( Some ( added) , renamed , _) if renamed . iter ( ) . any ( |r| * r. since == * added. since ) => {
186
+ ( Some ( added) , changed , _) if changed . iter ( ) . any ( |r| * r. since == * added. since ) => {
196
187
Err ( Error :: custom ( format ! (
197
- "{item_type} cannot be marked as `added` and `renamed ` in the same version"
188
+ "{item_type} cannot be marked as `added` and `changed ` in the same version"
198
189
) )
199
190
. with_span ( item_ident) )
200
191
}
201
- ( _, renamed , Some ( deprecated) )
202
- if renamed . iter ( ) . any ( |r| * r. since == * deprecated. since ) =>
192
+ ( _, changed , Some ( deprecated) )
193
+ if changed . iter ( ) . any ( |r| * r. since == * deprecated. since ) =>
203
194
{
204
195
Err ( Error :: custom (
205
- format ! ( "{item_type} cannot be marked as `deprecated` and `renamed ` in the same version" ) ,
196
+ format ! ( "{item_type} cannot be marked as `deprecated` and `changed ` in the same version" ) ,
206
197
)
207
198
. with_span ( item_ident) )
208
199
}
@@ -220,7 +211,7 @@ impl ItemAttributes {
220
211
/// ensures that these versions are chronologically sound, that means,
221
212
/// that the version of the deprecated action must be greater than the
222
213
/// version of the added action.
223
- /// - All `renamed ` actions must use a greater version than `added` but a
214
+ /// - All `changed ` actions must use a greater version than `added` but a
224
215
/// lesser version than `deprecated`.
225
216
fn validate_action_order ( & self , item_ident : & Ident , item_type : & ItemType ) -> Result < ( ) , Error > {
226
217
let added_version = self . added . as_ref ( ) . map ( |a| * a. since ) ;
@@ -238,14 +229,14 @@ impl ItemAttributes {
238
229
}
239
230
}
240
231
241
- // Now, iterate over all renames and ensure that their versions are
232
+ // Now, iterate over all changes and ensure that their versions are
242
233
// between the added and deprecated version.
243
- if !self . renames . iter ( ) . all ( |r| {
234
+ if !self . changes . iter ( ) . all ( |r| {
244
235
added_version. map_or ( true , |a| a < * r. since )
245
236
&& deprecated_version. map_or ( true , |d| d > * r. since )
246
237
} ) {
247
238
return Err ( Error :: custom (
248
- "all renames must use versions higher than `added` and lower than `deprecated`" ,
239
+ "all changes must use versions higher than `added` and lower than `deprecated`" ,
249
240
)
250
241
. with_span ( item_ident) ) ;
251
242
}
@@ -320,27 +311,32 @@ pub(crate) struct AddedAttributes {
320
311
321
312
fn default_default_fn ( ) -> SpannedValue < Path > {
322
313
SpannedValue :: new (
323
- syn:: parse_str ( "std::default::Default::default" ) . expect ( "internal error: path must parse" ) ,
314
+ syn:: parse_str ( "::std::default::Default::default" )
315
+ . expect ( "internal error: path must parse" ) ,
324
316
Span :: call_site ( ) ,
325
317
)
326
318
}
327
319
328
- /// For the renamed () action
320
+ /// For the changed () action
329
321
///
330
322
/// Example usage:
331
- /// - `renamed(since = "...", from = "...")`
323
+ /// - `changed(since = "...", from_name = "...")`
324
+ /// - `changed(since = "...", from_name = "..." from_type="...")`
332
325
#[ derive( Clone , Debug , FromMeta ) ]
333
- pub ( crate ) struct RenamedAttributes {
326
+ pub ( crate ) struct ChangedAttributes {
334
327
pub ( crate ) since : SpannedValue < Version > ,
335
- pub ( crate ) from : SpannedValue < String > ,
328
+ pub ( crate ) from_name : Option < SpannedValue < String > > ,
329
+
330
+ pub ( crate ) from_type : Option < SpannedValue < Type > > ,
336
331
}
337
332
338
333
/// For the deprecated() action
339
334
///
340
335
/// Example usage:
336
+ /// - `deprecated(since = "...")`
341
337
/// - `deprecated(since = "...", note = "...")`
342
338
#[ derive( Clone , Debug , FromMeta ) ]
343
339
pub ( crate ) struct DeprecatedAttributes {
344
340
pub ( crate ) since : SpannedValue < Version > ,
345
- pub ( crate ) note : SpannedValue < String > ,
341
+ pub ( crate ) note : Option < SpannedValue < String > > ,
346
342
}
0 commit comments