diff --git a/crates/stackable-versioned-macros/src/codegen/container/struct/k8s.rs b/crates/stackable-versioned-macros/src/codegen/container/struct/k8s.rs index c9fa59e3a..7023cca0c 100644 --- a/crates/stackable-versioned-macros/src/codegen/container/struct/k8s.rs +++ b/crates/stackable-versioned-macros/src/codegen/container/struct/k8s.rs @@ -280,19 +280,19 @@ impl Struct { impl #enum_ident { pub fn as_version_str(&self) -> &str { match self { - #(#variant_idents => #variant_strings),* + #(#enum_ident::#variant_idents => #variant_strings),* } } pub fn as_api_version_str(&self) -> &str { match self { - #(#variant_idents => #api_versions),* + #(#enum_ident::#variant_idents => #api_versions),* } } pub fn from_api_version(api_version: &str) -> Result { match api_version { - #(#api_versions => Ok(Self::#variant_idents)),*, + #(#api_versions => Ok(#enum_ident::#variant_idents)),*, _ => Err(#unknown_desired_api_version_error { api_version: api_version.to_owned(), }), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@basic.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@basic.rs.snap index fc3a3f401..cad771f3f 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@basic.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@basic.rs.snap @@ -388,25 +388,25 @@ impl ::std::fmt::Display for FooVersion { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1Beta1 => "v1beta1", - V1 => "v1", + FooVersion::V1Alpha1 => "v1alpha1", + FooVersion::V1Beta1 => "v1beta1", + FooVersion::V1 => "v1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "stackable.tech/v1alpha1", - V1Beta1 => "stackable.tech/v1beta1", - V1 => "stackable.tech/v1", + FooVersion::V1Alpha1 => "stackable.tech/v1alpha1", + FooVersion::V1Beta1 => "stackable.tech/v1beta1", + FooVersion::V1 => "stackable.tech/v1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "stackable.tech/v1alpha1" => Ok(Self::V1Alpha1), - "stackable.tech/v1beta1" => Ok(Self::V1Beta1), - "stackable.tech/v1" => Ok(Self::V1), + "stackable.tech/v1alpha1" => Ok(FooVersion::V1Alpha1), + "stackable.tech/v1beta1" => Ok(FooVersion::V1Beta1), + "stackable.tech/v1" => Ok(FooVersion::V1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@conversion_tracking.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@conversion_tracking.rs.snap index dc0969972..9a7ee26d5 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@conversion_tracking.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@conversion_tracking.rs.snap @@ -358,25 +358,25 @@ impl ::std::fmt::Display for FooVersion { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1Beta1 => "v1beta1", - V1 => "v1", + FooVersion::V1Alpha1 => "v1alpha1", + FooVersion::V1Beta1 => "v1beta1", + FooVersion::V1 => "v1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "stackable.tech/v1alpha1", - V1Beta1 => "stackable.tech/v1beta1", - V1 => "stackable.tech/v1", + FooVersion::V1Alpha1 => "stackable.tech/v1alpha1", + FooVersion::V1Beta1 => "stackable.tech/v1beta1", + FooVersion::V1 => "stackable.tech/v1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "stackable.tech/v1alpha1" => Ok(Self::V1Alpha1), - "stackable.tech/v1beta1" => Ok(Self::V1Beta1), - "stackable.tech/v1" => Ok(Self::V1), + "stackable.tech/v1alpha1" => Ok(FooVersion::V1Alpha1), + "stackable.tech/v1beta1" => Ok(FooVersion::V1Beta1), + "stackable.tech/v1" => Ok(FooVersion::V1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@crate_overrides.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@crate_overrides.rs.snap index 4a5d94073..2a120aa0e 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@crate_overrides.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@crate_overrides.rs.snap @@ -373,25 +373,25 @@ impl ::std::fmt::Display for FooVersion { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1Beta1 => "v1beta1", - V1 => "v1", + FooVersion::V1Alpha1 => "v1alpha1", + FooVersion::V1Beta1 => "v1beta1", + FooVersion::V1 => "v1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "foo.example.org/v1alpha1", - V1Beta1 => "foo.example.org/v1beta1", - V1 => "foo.example.org/v1", + FooVersion::V1Alpha1 => "foo.example.org/v1alpha1", + FooVersion::V1Beta1 => "foo.example.org/v1beta1", + FooVersion::V1 => "foo.example.org/v1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "foo.example.org/v1alpha1" => Ok(Self::V1Alpha1), - "foo.example.org/v1beta1" => Ok(Self::V1Beta1), - "foo.example.org/v1" => Ok(Self::V1), + "foo.example.org/v1alpha1" => Ok(FooVersion::V1Alpha1), + "foo.example.org/v1beta1" => Ok(FooVersion::V1Beta1), + "foo.example.org/v1" => Ok(FooVersion::V1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module.rs.snap index 9c3d2a6df..0eec1bba4 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module.rs.snap @@ -545,25 +545,25 @@ impl ::std::fmt::Display for FooVersion { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1 => "v1", - V2Alpha1 => "v2alpha1", + FooVersion::V1Alpha1 => "v1alpha1", + FooVersion::V1 => "v1", + FooVersion::V2Alpha1 => "v2alpha1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "foo.example.org/v1alpha1", - V1 => "foo.example.org/v1", - V2Alpha1 => "foo.example.org/v2alpha1", + FooVersion::V1Alpha1 => "foo.example.org/v1alpha1", + FooVersion::V1 => "foo.example.org/v1", + FooVersion::V2Alpha1 => "foo.example.org/v2alpha1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "foo.example.org/v1alpha1" => Ok(Self::V1Alpha1), - "foo.example.org/v1" => Ok(Self::V1), - "foo.example.org/v2alpha1" => Ok(Self::V2Alpha1), + "foo.example.org/v1alpha1" => Ok(FooVersion::V1Alpha1), + "foo.example.org/v1" => Ok(FooVersion::V1), + "foo.example.org/v2alpha1" => Ok(FooVersion::V2Alpha1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), @@ -842,25 +842,25 @@ impl ::std::fmt::Display for BarVersion { impl BarVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1 => "v1", - V2Alpha1 => "v2alpha1", + BarVersion::V1Alpha1 => "v1alpha1", + BarVersion::V1 => "v1", + BarVersion::V2Alpha1 => "v2alpha1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "bar.example.org/v1alpha1", - V1 => "bar.example.org/v1", - V2Alpha1 => "bar.example.org/v2alpha1", + BarVersion::V1Alpha1 => "bar.example.org/v1alpha1", + BarVersion::V1 => "bar.example.org/v1", + BarVersion::V2Alpha1 => "bar.example.org/v2alpha1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "bar.example.org/v1alpha1" => Ok(Self::V1Alpha1), - "bar.example.org/v1" => Ok(Self::V1), - "bar.example.org/v2alpha1" => Ok(Self::V2Alpha1), + "bar.example.org/v1alpha1" => Ok(BarVersion::V1Alpha1), + "bar.example.org/v1" => Ok(BarVersion::V1), + "bar.example.org/v2alpha1" => Ok(BarVersion::V2Alpha1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module_preserve.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module_preserve.rs.snap index 6208b1042..40f611cc6 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module_preserve.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@module_preserve.rs.snap @@ -523,25 +523,25 @@ pub(crate) mod versioned { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1 => "v1", - V2Alpha1 => "v2alpha1", + FooVersion::V1Alpha1 => "v1alpha1", + FooVersion::V1 => "v1", + FooVersion::V2Alpha1 => "v2alpha1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "foo.example.org/v1alpha1", - V1 => "foo.example.org/v1", - V2Alpha1 => "foo.example.org/v2alpha1", + FooVersion::V1Alpha1 => "foo.example.org/v1alpha1", + FooVersion::V1 => "foo.example.org/v1", + FooVersion::V2Alpha1 => "foo.example.org/v2alpha1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "foo.example.org/v1alpha1" => Ok(Self::V1Alpha1), - "foo.example.org/v1" => Ok(Self::V1), - "foo.example.org/v2alpha1" => Ok(Self::V2Alpha1), + "foo.example.org/v1alpha1" => Ok(FooVersion::V1Alpha1), + "foo.example.org/v1" => Ok(FooVersion::V1), + "foo.example.org/v2alpha1" => Ok(FooVersion::V2Alpha1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), @@ -815,25 +815,25 @@ pub(crate) mod versioned { impl BarVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1 => "v1", - V2Alpha1 => "v2alpha1", + BarVersion::V1Alpha1 => "v1alpha1", + BarVersion::V1 => "v1", + BarVersion::V2Alpha1 => "v2alpha1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "bar.example.org/v1alpha1", - V1 => "bar.example.org/v1", - V2Alpha1 => "bar.example.org/v2alpha1", + BarVersion::V1Alpha1 => "bar.example.org/v1alpha1", + BarVersion::V1 => "bar.example.org/v1", + BarVersion::V2Alpha1 => "bar.example.org/v2alpha1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "bar.example.org/v1alpha1" => Ok(Self::V1Alpha1), - "bar.example.org/v1" => Ok(Self::V1), - "bar.example.org/v2alpha1" => Ok(Self::V2Alpha1), + "bar.example.org/v1alpha1" => Ok(BarVersion::V1Alpha1), + "bar.example.org/v1" => Ok(BarVersion::V1), + "bar.example.org/v2alpha1" => Ok(BarVersion::V2Alpha1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@renamed_kind.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@renamed_kind.rs.snap index e71e3bfd2..899658557 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@renamed_kind.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@renamed_kind.rs.snap @@ -358,25 +358,25 @@ impl ::std::fmt::Display for FooBarVersion { impl FooBarVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", - V1Beta1 => "v1beta1", - V1 => "v1", + FooBarVersion::V1Alpha1 => "v1alpha1", + FooBarVersion::V1Beta1 => "v1beta1", + FooBarVersion::V1 => "v1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "stackable.tech/v1alpha1", - V1Beta1 => "stackable.tech/v1beta1", - V1 => "stackable.tech/v1", + FooBarVersion::V1Alpha1 => "stackable.tech/v1alpha1", + FooBarVersion::V1Beta1 => "stackable.tech/v1beta1", + FooBarVersion::V1 => "stackable.tech/v1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "stackable.tech/v1alpha1" => Ok(Self::V1Alpha1), - "stackable.tech/v1beta1" => Ok(Self::V1Beta1), - "stackable.tech/v1" => Ok(Self::V1), + "stackable.tech/v1alpha1" => Ok(FooBarVersion::V1Alpha1), + "stackable.tech/v1beta1" => Ok(FooBarVersion::V1Beta1), + "stackable.tech/v1" => Ok(FooBarVersion::V1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@shortnames.rs.snap b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@shortnames.rs.snap index 111436af9..6d0d019fc 100644 --- a/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@shortnames.rs.snap +++ b/crates/stackable-versioned-macros/tests/snapshots/stackable_versioned_macros__snapshot_tests__k8s@shortnames.rs.snap @@ -189,19 +189,19 @@ impl ::std::fmt::Display for FooVersion { impl FooVersion { pub fn as_version_str(&self) -> &str { match self { - V1Alpha1 => "v1alpha1", + FooVersion::V1Alpha1 => "v1alpha1", } } pub fn as_api_version_str(&self) -> &str { match self { - V1Alpha1 => "stackable.tech/v1alpha1", + FooVersion::V1Alpha1 => "stackable.tech/v1alpha1", } } pub fn from_api_version( api_version: &str, ) -> Result { match api_version { - "stackable.tech/v1alpha1" => Ok(Self::V1Alpha1), + "stackable.tech/v1alpha1" => Ok(FooVersion::V1Alpha1), _ => { Err(::stackable_versioned::UnknownDesiredApiVersionError { api_version: api_version.to_owned(), diff --git a/crates/stackable-versioned/CHANGELOG.md b/crates/stackable-versioned/CHANGELOG.md index 58968d114..8435ff4c1 100644 --- a/crates/stackable-versioned/CHANGELOG.md +++ b/crates/stackable-versioned/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix incorrectly generated match arms for the version enum ([#1065]). - Fix regression introduced in [#1033]. The `#[kube(status = ...)]` attribute is generated correctly again ([#1046]). - Correctly handle fields added in later versions ([#1031]). @@ -55,6 +56,7 @@ All notable changes to this project will be documented in this file. [#1050]: https://github.com/stackabletech/operator-rs/pull/1050 [#1059]: https://github.com/stackabletech/operator-rs/pull/1059 [#1061]: https://github.com/stackabletech/operator-rs/pull/1061 +[#1065]: https://github.com/stackabletech/operator-rs/pull/1065 ## [0.7.1] - 2025-04-02 diff --git a/crates/stackable-versioned/tests/conversions.rs b/crates/stackable-versioned/tests/conversions.rs index 034454001..c5bb0e337 100644 --- a/crates/stackable-versioned/tests/conversions.rs +++ b/crates/stackable-versioned/tests/conversions.rs @@ -1,87 +1,11 @@ use std::{fs::File, path::Path}; use insta::{assert_snapshot, glob}; -use kube::{ - CustomResource, - core::{conversion::ConversionReview, response::StatusSummary}, -}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; -use stackable_versioned::versioned; +use kube::core::{conversion::ConversionReview, response::StatusSummary}; -#[versioned( - k8s(group = "test.stackable.tech",), - version(name = "v1alpha1"), - version(name = "v1alpha2"), - version(name = "v1beta1"), - version(name = "v2"), - version(name = "v3") -)] -#[derive( - Clone, - Debug, - Eq, - Hash, - Ord, - PartialEq, - PartialOrd, - CustomResource, - Deserialize, - JsonSchema, - Serialize, -)] -#[serde(rename_all = "camelCase")] -struct PersonSpec { - username: String, +use crate::person::Person; - // In v1alpha2 first and last name have been added - #[versioned(added(since = "v1alpha2"))] - first_name: String, - #[versioned(added(since = "v1alpha2"))] - last_name: String, - - // We started out with a enum. As we *need* to provide a default, we have a Unknown variant. - // Afterwards we figured let's be more flexible and accept any arbitrary String. - #[versioned( - added(since = "v2", default = "default_gender"), - changed(since = "v3", from_type = "Gender") - )] - gender: String, -} - -fn default_gender() -> Gender { - Gender::Unknown -} - -#[derive( - Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, JsonSchema, Serialize, -)] -#[serde(rename_all = "PascalCase")] -pub enum Gender { - Unknown, - Male, - Female, -} - -impl From for String { - fn from(value: Gender) -> Self { - match value { - Gender::Unknown => "Unknown".to_owned(), - Gender::Male => "Male".to_owned(), - Gender::Female => "Female".to_owned(), - } - } -} - -impl From for Gender { - fn from(value: String) -> Self { - match value.as_str() { - "Male" => Self::Male, - "Female" => Self::Female, - _ => Self::Unknown, - } - } -} +mod person; #[test] fn pass() { diff --git a/crates/stackable-versioned/tests/merged_crd.rs b/crates/stackable-versioned/tests/merged_crd.rs new file mode 100644 index 000000000..95bec94cc --- /dev/null +++ b/crates/stackable-versioned/tests/merged_crd.rs @@ -0,0 +1,22 @@ +use crate::person::{Person, PersonVersion}; + +mod person; + +#[test] +fn stored_apiversion() { + let stored_apiversion = PersonVersion::V2; + + let merged_crd = Person::merged_crd(stored_apiversion).expect("the CRDs must be mergeable"); + + // We ensure that the merged CRD contains at least one version marked as + // storage = true. + let crd = merged_crd + .spec + .versions + .iter() + .find(|crd| crd.storage) + .expect("The merged CRD must contain at least one version marked with storage = true"); + + // This asserts that the name (version) of the CRD matches the one we expect + assert_eq!(crd.name, stored_apiversion.as_version_str()); +} diff --git a/crates/stackable-versioned/tests/person.rs b/crates/stackable-versioned/tests/person.rs new file mode 100644 index 000000000..f2610fa60 --- /dev/null +++ b/crates/stackable-versioned/tests/person.rs @@ -0,0 +1,78 @@ +use kube::CustomResource; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use stackable_versioned::versioned; + +#[versioned( + k8s(group = "test.stackable.tech",), + version(name = "v1alpha1"), + version(name = "v1alpha2"), + version(name = "v1beta1"), + version(name = "v2"), + version(name = "v3") +)] +#[derive( + Clone, + Debug, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + CustomResource, + Deserialize, + JsonSchema, + Serialize, +)] +#[serde(rename_all = "camelCase")] +pub struct PersonSpec { + username: String, + + // In v1alpha2 first and last name have been added + #[versioned(added(since = "v1alpha2"))] + first_name: String, + #[versioned(added(since = "v1alpha2"))] + last_name: String, + + // We started out with a enum. As we *need* to provide a default, we have a Unknown variant. + // Afterwards we figured let's be more flexible and accept any arbitrary String. + #[versioned( + added(since = "v2", default = "default_gender"), + changed(since = "v3", from_type = "Gender") + )] + gender: String, +} + +fn default_gender() -> Gender { + Gender::Unknown +} + +#[derive( + Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, JsonSchema, Serialize, +)] +#[serde(rename_all = "PascalCase")] +pub enum Gender { + Unknown, + Male, + Female, +} + +impl From for String { + fn from(value: Gender) -> Self { + match value { + Gender::Unknown => "Unknown".to_owned(), + Gender::Male => "Male".to_owned(), + Gender::Female => "Female".to_owned(), + } + } +} + +impl From for Gender { + fn from(value: String) -> Self { + match value.as_str() { + "Male" => Self::Male, + "Female" => Self::Female, + _ => Self::Unknown, + } + } +}