Skip to content

Commit c9e3331

Browse files
committed
feat(stackable-versioned): Add conditional allow attr generation
1 parent 7ba94b5 commit c9e3331

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

crates/stackable-versioned-macros/src/codegen/chain.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ where
55
K: Ord + Eq,
66
{
77
fn get_neighbors(&self, key: &K) -> (Option<&V>, Option<&V>);
8+
fn value_is<F>(&self, key: &K, f: F) -> bool
9+
where
10+
F: Fn(&V) -> bool;
811

912
fn lo_bound(&self, bound: Bound<&K>) -> Option<(&K, &V)>;
1013
fn up_bound(&self, bound: Bound<&K>) -> Option<(&K, &V)>;
@@ -51,6 +54,13 @@ where
5154
}
5255
}
5356

57+
fn value_is<F>(&self, key: &K, f: F) -> bool
58+
where
59+
F: Fn(&V) -> bool,
60+
{
61+
self.get(key).map_or(false, f)
62+
}
63+
5464
fn lo_bound(&self, bound: Bound<&K>) -> Option<(&K, &V)> {
5565
self.range((Bound::Unbounded, bound)).next_back()
5666
}

crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ use syn::{parse_quote, DataStruct, Error, Ident};
88
use crate::{
99
attrs::common::ContainerAttributes,
1010
codegen::{
11+
chain::Neighbors,
1112
common::{
12-
Container, ContainerInput, ContainerVersion, Item, VersionExt, VersionedContainer,
13+
Container, ContainerInput, ContainerVersion, Item, ItemStatus, VersionExt,
14+
VersionedContainer,
1315
},
1416
vstruct::field::VersionedField,
1517
},
@@ -241,11 +243,20 @@ impl VersionedStruct {
241243

242244
let fields = self.generate_from_fields(version, next_version, from_ident);
243245

246+
// Include allow(deprecated) only when this or the next version is
247+
// deprecated. Also include it, when a field in this or the next
248+
// version is deprecated.
249+
let allow_attribute = (version.deprecated
250+
|| next_version.deprecated
251+
|| self.any_field_deprecated(version)
252+
|| self.any_field_deprecated(next_version))
253+
.then_some(quote! { #[allow(deprecated)] });
254+
244255
// TODO (@Techassi): Be a little bit more clever about when to include
245256
// the #[allow(deprecated)] attribute.
246257
return Some(quote! {
247258
#[automatically_derived]
248-
#[allow(deprecated)]
259+
#allow_attribute
249260
impl From<#module_name::#struct_ident> for #next_module_name::#struct_ident {
250261
fn from(#from_ident: #module_name::#struct_ident) -> Self {
251262
Self {
@@ -275,6 +286,25 @@ impl VersionedStruct {
275286

276287
token_stream
277288
}
289+
290+
/// Returns whether any field is deprecated in the provided
291+
/// [`ContainerVersion`].
292+
fn any_field_deprecated(&self, version: &ContainerVersion) -> bool {
293+
// First, iterate over all fields. Any will return true if any of the
294+
// function invocations return true. If a field doesn't have a chain,
295+
// we can safely default to false (unversioned fields cannot be
296+
// deprecated). Then we retrieve the status of the field and ensure it
297+
// is deprecated.
298+
// TODO (@Techassi): This currently does not include fields which were
299+
// already deprecated and thus now have the NoChange status.
300+
self.items.iter().any(|f| {
301+
f.chain.as_ref().map_or(false, |c| {
302+
c.value_is(&version.inner, |a| {
303+
matches!(a, ItemStatus::Deprecation { .. })
304+
})
305+
})
306+
})
307+
}
278308
}
279309

280310
// Kubernetes specific code generation

crates/stackable-versioned-macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ pub struct FooSpec {
456456
}
457457
458458
# fn main() {
459-
let merged_crd = Foo::merged_crd("v1").unwrap();
459+
let merged_crd = Foo::merged_crd(Foo::V1).unwrap();
460460
println!("{}", serde_yaml::to_string(&merged_crd).unwrap());
461461
# }
462462
```

crates/stackable-versioned-macros/tests/default/pass/deprecate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn main() {
77
version(name = "v1")
88
)]
99
struct Foo {
10-
#[versioned(deprecated(since = "v1beta1", note = "gone"))]
10+
#[versioned(deprecated(since = "v1", note = "gone"))]
1111
deprecated_bar: usize,
1212
baz: bool,
1313
}

0 commit comments

Comments
 (0)