Skip to content

Commit 1c2d22c

Browse files
feat(stackable-versioned): Generate From implementations for automatic versions upgrades (#790)
* Add basic From impl generation * Merge branch 'main' into feat/crd-versioning-from-impls * Separate code, re-add basic From impl, separate generation code This commit separate the code into two crates: the core stackable-versioned crate, which provides a few utility traits and types and also re-exports the macros from the stackable-versioned-macros crate. This is because, crates (or libraries) marked as proc-macro libraries don't support export anything other than macro items. It also re-adds the basic From impl which was hard to keep across the previous merge conflict. This basic impl will currently panic, as the inner function is not yet implemented. This will follow. It additionally separates the generation code into multiple functions to more easily generate the different parts of code, like modules, struct fields and From impls. * Generate working inner From trait function There is at least one known rough edge: The #[allow(deprecated)] attribute is always included in the generated output, regardless if the individual From implementation actually needs it. The attribute is only required when the next version of the struct includes a field which is marked as deprecated. * Add option to skip From trait implementation generation Can be skipped both on the container level (no impls are generated) or at the version level (no impls are generated for that version). * Add README * Add basic support for custom default function * Fix doc test * Add TODOs * Start adding doc comments * Finish doc comment * Fix changelog * Fix doc tests * Update crates/stackable-versioned-macros/src/lib.rs Co-authored-by: Nick <[email protected]> * Remove redundant code block in doc comment --------- Co-authored-by: Nick <[email protected]>
1 parent 84646f2 commit 1c2d22c

File tree

19 files changed

+791
-234
lines changed

19 files changed

+791
-234
lines changed

Cargo.lock

+9-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "stackable-versioned-macros"
3+
version = "0.1.0"
4+
authors.workspace = true
5+
license.workspace = true
6+
edition.workspace = true
7+
repository.workspace = true
8+
9+
[lib]
10+
proc-macro = true
11+
12+
[dependencies]
13+
k8s-version = { path = "../k8s-version", features = ["darling"] }
14+
15+
darling.workspace = true
16+
proc-macro2.workspace = true
17+
syn.workspace = true
18+
quote.workspace = true
19+
20+
[dev-dependencies]
21+
rstest.workspace = true

crates/stackable-versioned/src/attrs/container.rs renamed to crates/stackable-versioned-macros/src/attrs/container.rs

+18
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ impl ContainerAttributes {
5959
}
6060
}
6161

62+
// TODO (@Techassi): Add validation for skip(from) for last version,
63+
// which will skip nothing, because nothing is generated in the first
64+
// place.
65+
6266
// Ensure every version is unique and isn't declared multiple times. This
6367
// is inspired by the itertools all_unique function.
6468
let mut unique = HashSet::new();
@@ -83,10 +87,12 @@ impl ContainerAttributes {
8387
///
8488
/// - `name` of the version, like `v1alpha1`.
8589
/// - `deprecated` flag to mark that version as deprecated.
90+
/// - `skip` option to skip generating various pieces of code.
8691
#[derive(Clone, Debug, FromMeta)]
8792
pub(crate) struct VersionAttributes {
8893
pub(crate) deprecated: Flag,
8994
pub(crate) name: Version,
95+
pub(crate) skip: Option<SkipOptions>,
9096
}
9197

9298
/// This struct contains supported container options.
@@ -95,7 +101,19 @@ pub(crate) struct VersionAttributes {
95101
///
96102
/// - `allow_unsorted`, which allows declaring versions in unsorted order,
97103
/// instead of enforcing ascending order.
104+
/// - `skip` option to skip generating various pieces of code.
98105
#[derive(Clone, Debug, Default, FromMeta)]
99106
pub(crate) struct ContainerOptions {
100107
pub(crate) allow_unsorted: Flag,
108+
pub(crate) skip: Option<SkipOptions>,
109+
}
110+
111+
/// This struct contains supported skip options.
112+
///
113+
/// Supported options are:
114+
///
115+
/// - `from` flag, which skips generating [`From`] implementations when provided.
116+
#[derive(Clone, Debug, Default, FromMeta)]
117+
pub(crate) struct SkipOptions {
118+
pub(crate) from: Flag,
101119
}

crates/stackable-versioned/src/attrs/field.rs renamed to crates/stackable-versioned-macros/src/attrs/field.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use darling::{util::SpannedValue, Error, FromField, FromMeta};
22
use k8s_version::Version;
3-
use syn::{Field, Ident};
3+
use proc_macro2::Span;
4+
use syn::{Field, Ident, Path};
45

56
use crate::{attrs::container::ContainerAttributes, consts::DEPRECATED_PREFIX};
67

@@ -40,6 +41,16 @@ pub(crate) struct FieldAttributes {
4041
#[derive(Clone, Debug, FromMeta)]
4142
pub(crate) struct AddedAttributes {
4243
pub(crate) since: SpannedValue<Version>,
44+
45+
#[darling(rename = "default", default = "default_default_fn")]
46+
pub(crate) default_fn: SpannedValue<Path>,
47+
}
48+
49+
fn default_default_fn() -> SpannedValue<Path> {
50+
SpannedValue::new(
51+
syn::parse_str("std::default::Default::default").unwrap(),
52+
Span::call_site(),
53+
)
4354
}
4455

4556
#[derive(Clone, Debug, FromMeta)]
@@ -139,6 +150,7 @@ impl FieldAttributes {
139150

140151
// First, validate that the added version is less than the deprecated
141152
// version.
153+
// NOTE (@Techassi): Is this already covered by the code below?
142154
if let (Some(added_version), Some(deprecated_version)) = (added_version, deprecated_version)
143155
{
144156
if added_version >= deprecated_version {

0 commit comments

Comments
 (0)