Skip to content

Commit cd125d2

Browse files
committed
fix: Correctly emit automatically_derived and deprecated attributes
1 parent a922c60 commit cd125d2

File tree

6 files changed

+54
-20
lines changed

6 files changed

+54
-20
lines changed

crates/stackable-versioned-macros/src/attrs/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use darling::{
2-
util::{Flag, SpannedValue},
2+
util::{Flag, Override, SpannedValue},
33
Error, FromMeta, Result,
44
};
55
use itertools::Itertools;
@@ -75,7 +75,7 @@ pub(crate) struct RootOptions {
7575
/// - `doc` option to add version-specific documentation.
7676
#[derive(Clone, Debug, FromMeta)]
7777
pub(crate) struct VersionArguments {
78-
pub(crate) deprecated: Flag,
78+
pub(crate) deprecated: Option<Override<String>>,
7979
pub(crate) name: Version,
8080
pub(crate) skip: Option<SkipArguments>,
8181
pub(crate) doc: Option<String>,

crates/stackable-versioned-macros/src/codegen/container/enum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ impl Enum {
139139
// Include allow(deprecated) only when this or the next version is
140140
// deprecated. Also include it, when a variant in this or the next
141141
// version is deprecated.
142-
let allow_attribute = (version.deprecated
143-
|| next_version.deprecated
142+
let allow_attribute = (version.deprecated.is_some()
143+
|| next_version.deprecated.is_some()
144144
|| self.is_any_variant_deprecated(version)
145145
|| self.is_any_variant_deprecated(next_version))
146146
.then_some(quote! { #[allow(deprecated)] });

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ impl Container {
4343
&self,
4444
version: &VersionDefinition,
4545
next_version: Option<&VersionDefinition>,
46-
is_nested: bool,
46+
add_attributes: bool,
4747
) -> Option<TokenStream> {
4848
match self {
49-
Container::Struct(s) => s.generate_from_impl(version, next_version, is_nested),
50-
Container::Enum(e) => e.generate_from_impl(version, next_version, is_nested),
49+
Container::Struct(s) => s.generate_from_impl(version, next_version, add_attributes),
50+
Container::Enum(e) => e.generate_from_impl(version, next_version, add_attributes),
5151
}
5252
}
5353

@@ -135,6 +135,12 @@ impl StandaloneContainer {
135135
self.container
136136
.generate_from_impl(version, versions.peek().copied(), false);
137137

138+
// Add the #[deprecated] attribute when the version is marked as deprecated.
139+
let deprecated_attribute = version
140+
.deprecated
141+
.as_ref()
142+
.map(|note| quote! { #[deprecated = #note] });
143+
138144
// Generate Kubernetes specific code which is placed outside of the container
139145
// definition.
140146
if let Some((enum_variant, fn_call)) = self.container.generate_kubernetes_item(version)
@@ -146,7 +152,10 @@ impl StandaloneContainer {
146152
let version_ident = &version.ident;
147153

148154
tokens.extend(quote! {
155+
#[automatically_derived]
156+
#deprecated_attribute
149157
#vis mod #version_ident {
158+
use super::*;
150159
#container_definition
151160
}
152161

crates/stackable-versioned-macros/src/codegen/container/struct.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,6 @@ impl Container {
103103
common,
104104
}))
105105
}
106-
107-
fn new_struct() -> Result<Self> {
108-
todo!()
109-
}
110106
}
111107

112108
pub(crate) struct Struct {
@@ -143,7 +139,7 @@ impl Struct {
143139
&self,
144140
version: &VersionDefinition,
145141
next_version: Option<&VersionDefinition>,
146-
is_nested: bool,
142+
add_attributes: bool,
147143
) -> Option<TokenStream> {
148144
if version.skip_from || self.common.options.skip_from {
149145
return None;
@@ -162,16 +158,17 @@ impl Struct {
162158
// Include allow(deprecated) only when this or the next version is
163159
// deprecated. Also include it, when a field in this or the next
164160
// version is deprecated.
165-
let allow_attribute = (version.deprecated
166-
|| next_version.deprecated
161+
let allow_attribute = (version.deprecated.is_some()
162+
|| next_version.deprecated.is_some()
167163
|| self.is_any_field_deprecated(version)
168164
|| self.is_any_field_deprecated(next_version))
169165
.then(|| quote! { #[allow(deprecated)] });
170166

171167
// Only add the #[automatically_derived] attribute only if this impl is used
172168
// outside of a module (in standalone mode).
173-
let automatically_derived =
174-
is_nested.not().then(|| quote! {#[automatically_derived]});
169+
let automatically_derived = add_attributes
170+
.not()
171+
.then(|| quote! {#[automatically_derived]});
175172

176173
Some(quote! {
177174
#automatically_derived

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub(crate) mod module;
1313
#[derive(Debug)]
1414
pub(crate) struct VersionDefinition {
1515
/// Indicates that the container version is deprecated.
16-
pub(crate) deprecated: bool,
16+
pub(crate) deprecated: Option<String>,
1717

1818
/// Indicates that the generation of `From<OLD> for NEW` should be skipped.
1919
pub(crate) skip_from: bool,
@@ -38,7 +38,12 @@ impl From<&StandaloneContainerAttributes> for Vec<VersionDefinition> {
3838
.map(|v| VersionDefinition {
3939
skip_from: v.skip.as_ref().map_or(false, |s| s.from.is_present()),
4040
ident: format_ident!("{version}", version = v.name.to_string()).into(),
41-
deprecated: v.deprecated.is_present(),
41+
deprecated: v.deprecated.as_ref().map(|r#override| {
42+
r#override.clone().unwrap_or(format!(
43+
"Version {version} is deprecated",
44+
version = v.name.to_string()
45+
))
46+
}),
4247
docs: process_docs(&v.doc),
4348
inner: v.name,
4449
})
@@ -55,7 +60,12 @@ impl From<&ModuleAttributes> for Vec<VersionDefinition> {
5560
.map(|v| VersionDefinition {
5661
skip_from: v.skip.as_ref().map_or(false, |s| s.from.is_present()),
5762
ident: format_ident!("{version}", version = v.name.to_string()).into(),
58-
deprecated: v.deprecated.is_present(),
63+
deprecated: v.deprecated.as_ref().map(|r#override| {
64+
r#override.clone().unwrap_or(format!(
65+
"Version {version} is deprecated",
66+
version = v.name.to_string()
67+
))
68+
}),
5969
docs: process_docs(&v.doc),
6070
inner: v.name,
6171
})

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::ops::Not;
2+
13
use darling::util::IdentString;
24
use proc_macro2::TokenStream;
35
use quote::quote;
@@ -64,11 +66,26 @@ impl Module {
6466
from_impls.extend(container.generate_from_impl(
6567
version,
6668
versions.peek().copied(),
67-
true,
69+
self.preserve_module,
6870
));
6971
}
7072

73+
// Only add #[automatically_derived] here if the user doesn't want to preserve the
74+
// module.
75+
let automatically_derived = self
76+
.preserve_module
77+
.not()
78+
.then(|| quote! {#[automatically_derived]});
79+
80+
// Add the #[deprecated] attribute when the version is marked as deprecated.
81+
let deprecated_attribute = version
82+
.deprecated
83+
.as_ref()
84+
.map(|note| quote! { #[deprecated = #note] });
85+
7186
tokens.extend(quote! {
87+
#automatically_derived
88+
#deprecated_attribute
7289
#version_module_vis mod #version_ident {
7390
use super::*;
7491

@@ -81,6 +98,7 @@ impl Module {
8198

8299
if self.preserve_module {
83100
quote! {
101+
#[automatically_derived]
84102
#module_vis mod #module_ident {
85103
#tokens
86104
}

0 commit comments

Comments
 (0)