From 716f905aef0e7b423ec38666e31f7621355db77c Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 15:04:14 +0200 Subject: [PATCH 1/6] feat(k8s-version): Add serde support --- Cargo.lock | 1 + crates/k8s-version/Cargo.toml | 2 + .../{api_version.rs => api_version/mod.rs} | 3 ++ crates/k8s-version/src/api_version/serde.rs | 40 +++++++++++++++++++ .../src/{group.rs => group/mod.rs} | 3 ++ crates/k8s-version/src/group/serde.rs | 40 +++++++++++++++++++ .../src/{level.rs => level/mod.rs} | 34 +++------------- crates/k8s-version/src/level/serde.rs | 40 +++++++++++++++++++ .../src/{version.rs => version/mod.rs} | 35 +++------------- crates/k8s-version/src/version/serde.rs | 40 +++++++++++++++++++ 10 files changed, 181 insertions(+), 57 deletions(-) rename crates/k8s-version/src/{api_version.rs => api_version/mod.rs} (99%) create mode 100644 crates/k8s-version/src/api_version/serde.rs rename crates/k8s-version/src/{group.rs => group/mod.rs} (97%) create mode 100644 crates/k8s-version/src/group/serde.rs rename crates/k8s-version/src/{level.rs => level/mod.rs} (82%) create mode 100644 crates/k8s-version/src/level/serde.rs rename crates/k8s-version/src/{version.rs => version/mod.rs} (81%) create mode 100644 crates/k8s-version/src/version/serde.rs diff --git a/Cargo.lock b/Cargo.lock index c8fd63dba..8502754b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1657,6 +1657,7 @@ dependencies = [ "regex", "rstest", "rstest_reuse", + "serde", "snafu 0.8.5", "syn 2.0.101", ] diff --git a/crates/k8s-version/Cargo.toml b/crates/k8s-version/Cargo.toml index 1bebaf206..de550e5f5 100644 --- a/crates/k8s-version/Cargo.toml +++ b/crates/k8s-version/Cargo.toml @@ -8,10 +8,12 @@ repository.workspace = true [features] darling = ["dep:darling"] +serde = ["dep:serde"] [dependencies] darling = { workspace = true, optional = true } regex.workspace = true +serde = { workspace = true, optional = true } snafu.workspace = true [dev-dependencies] diff --git a/crates/k8s-version/src/api_version.rs b/crates/k8s-version/src/api_version/mod.rs similarity index 99% rename from crates/k8s-version/src/api_version.rs rename to crates/k8s-version/src/api_version/mod.rs index f3157647e..5f046a869 100644 --- a/crates/k8s-version/src/api_version.rs +++ b/crates/k8s-version/src/api_version/mod.rs @@ -6,6 +6,9 @@ use snafu::{ResultExt, Snafu}; use crate::{Group, ParseGroupError, ParseVersionError, Version}; +#[cfg(feature = "serde")] +mod serde; + /// Error variants which can be encountered when creating a new [`ApiVersion`] /// from unparsed input. #[derive(Debug, PartialEq, Snafu)] diff --git a/crates/k8s-version/src/api_version/serde.rs b/crates/k8s-version/src/api_version/serde.rs new file mode 100644 index 000000000..abacb0412 --- /dev/null +++ b/crates/k8s-version/src/api_version/serde.rs @@ -0,0 +1,40 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize, de::Visitor}; + +use crate::ApiVersion; + +impl<'de> Deserialize<'de> for ApiVersion { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ApiVersionVisitor; + + impl<'de> Visitor<'de> for ApiVersionVisitor { + type Value = ApiVersion; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a valid Kubernetes API version") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + ApiVersion::from_str(v).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_str(ApiVersionVisitor) + } +} + +impl Serialize for ApiVersion { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} diff --git a/crates/k8s-version/src/group.rs b/crates/k8s-version/src/group/mod.rs similarity index 97% rename from crates/k8s-version/src/group.rs rename to crates/k8s-version/src/group/mod.rs index ebe7c912b..b2f7ff47c 100644 --- a/crates/k8s-version/src/group.rs +++ b/crates/k8s-version/src/group/mod.rs @@ -3,6 +3,9 @@ use std::{fmt, ops::Deref, str::FromStr, sync::LazyLock}; use regex::Regex; use snafu::{Snafu, ensure}; +#[cfg(feature = "serde")] +mod serde; + const MAX_GROUP_LENGTH: usize = 253; static API_GROUP_REGEX: LazyLock = LazyLock::new(|| { diff --git a/crates/k8s-version/src/group/serde.rs b/crates/k8s-version/src/group/serde.rs new file mode 100644 index 000000000..2fd8dd14e --- /dev/null +++ b/crates/k8s-version/src/group/serde.rs @@ -0,0 +1,40 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize, de::Visitor}; + +use crate::Group; + +impl<'de> Deserialize<'de> for Group { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct GroupVisitor; + + impl<'de> Visitor<'de> for GroupVisitor { + type Value = Group; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a valid Kubernetes API group") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Group::from_str(v).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_str(GroupVisitor) + } +} + +impl Serialize for Group { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self) + } +} diff --git a/crates/k8s-version/src/level.rs b/crates/k8s-version/src/level/mod.rs similarity index 82% rename from crates/k8s-version/src/level.rs rename to crates/k8s-version/src/level/mod.rs index 15a49b02b..1e10006d9 100644 --- a/crates/k8s-version/src/level.rs +++ b/crates/k8s-version/src/level/mod.rs @@ -7,11 +7,15 @@ use std::{ sync::LazyLock, }; -#[cfg(feature = "darling")] -use darling::FromMeta; use regex::Regex; use snafu::{OptionExt, ResultExt, Snafu}; +#[cfg(feature = "serde")] +mod serde; + +#[cfg(feature = "darling")] +mod darling; + static LEVEL_REGEX: LazyLock = LazyLock::new(|| { Regex::new(r"^(?P[a-z]+)(?P\d+)$").expect("failed to compile level regex") }); @@ -148,28 +152,13 @@ impl Display for Level { } } -#[cfg(feature = "darling")] -impl FromMeta for Level { - fn from_string(value: &str) -> darling::Result { - Self::from_str(value).map_err(darling::Error::custom) - } -} - #[cfg(test)] mod test { - #[cfg(feature = "darling")] - use quote::quote; use rstest::rstest; use rstest_reuse::*; use super::*; - #[cfg(feature = "darling")] - fn parse_meta(tokens: proc_macro2::TokenStream) -> ::std::result::Result { - let attribute: syn::Attribute = syn::parse_quote!(#[#tokens]); - Ok(attribute.meta) - } - #[template] #[rstest] #[case(Level::Beta(1), Level::Alpha(1), Ordering::Greater)] @@ -191,15 +180,4 @@ mod test { fn partial_ord(input: Level, other: Level, expected: Ordering) { assert_eq!(input.partial_cmp(&other), Some(expected)) } - - #[cfg(feature = "darling")] - #[rstest] - #[case(quote!(ignore = "alpha12"), Level::Alpha(12))] - #[case(quote!(ignore = "alpha1"), Level::Alpha(1))] - #[case(quote!(ignore = "beta1"), Level::Beta(1))] - fn from_meta(#[case] input: proc_macro2::TokenStream, #[case] expected: Level) { - let meta = parse_meta(input).expect("valid attribute tokens"); - let version = Level::from_meta(&meta).expect("level must parse from attribute"); - assert_eq!(version, expected); - } } diff --git a/crates/k8s-version/src/level/serde.rs b/crates/k8s-version/src/level/serde.rs new file mode 100644 index 000000000..75b33db50 --- /dev/null +++ b/crates/k8s-version/src/level/serde.rs @@ -0,0 +1,40 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize, de::Visitor}; + +use crate::Level; + +impl<'de> Deserialize<'de> for Level { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct LevelVisitor; + + impl<'de> Visitor<'de> for LevelVisitor { + type Value = Level; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a valid Kubernetes API version level") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Level::from_str(v).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_str(LevelVisitor) + } +} + +impl Serialize for Level { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} diff --git a/crates/k8s-version/src/version.rs b/crates/k8s-version/src/version/mod.rs similarity index 81% rename from crates/k8s-version/src/version.rs rename to crates/k8s-version/src/version/mod.rs index ab6a2cc90..a145e8a31 100644 --- a/crates/k8s-version/src/version.rs +++ b/crates/k8s-version/src/version/mod.rs @@ -1,12 +1,16 @@ use std::{cmp::Ordering, fmt::Display, num::ParseIntError, str::FromStr, sync::LazyLock}; -#[cfg(feature = "darling")] -use darling::FromMeta; use regex::Regex; use snafu::{OptionExt, ResultExt, Snafu}; use crate::{Level, ParseLevelError}; +#[cfg(feature = "serde")] +mod serde; + +#[cfg(feature = "darling")] +mod darling; + static VERSION_REGEX: LazyLock = LazyLock::new(|| { Regex::new(r"^v(?P\d+)(?P[a-z0-9][a-z0-9-]{0,60}[a-z0-9])?$") .expect("failed to compile version regex") @@ -103,13 +107,6 @@ impl Display for Version { } } -#[cfg(feature = "darling")] -impl FromMeta for Version { - fn from_string(value: &str) -> darling::Result { - Self::from_str(value).map_err(darling::Error::custom) - } -} - impl Version { pub fn new(major: u64, level: Option) -> Self { Self { major, level } @@ -118,19 +115,11 @@ impl Version { #[cfg(test)] mod test { - #[cfg(feature = "darling")] - use quote::quote; use rstest::rstest; use rstest_reuse::{apply, template}; use super::*; - #[cfg(feature = "darling")] - fn parse_meta(tokens: proc_macro2::TokenStream) -> ::std::result::Result { - let attribute: syn::Attribute = syn::parse_quote!(#[#tokens]); - Ok(attribute.meta) - } - #[template] #[rstest] #[case(Version {major: 1, level: Some(Level::Beta(1))}, Version {major: 1, level: Some(Level::Alpha(1))}, Ordering::Greater)] @@ -167,16 +156,4 @@ mod test { fn partial_ord(input: Version, other: Version, expected: Ordering) { assert_eq!(input.partial_cmp(&other), Some(expected)) } - - #[cfg(feature = "darling")] - #[rstest] - #[case(quote!(ignore = "v1alpha12"), Version { major: 1, level: Some(Level::Alpha(12)) })] - #[case(quote!(ignore = "v1alpha1"), Version { major: 1, level: Some(Level::Alpha(1)) })] - #[case(quote!(ignore = "v1beta1"), Version { major: 1, level: Some(Level::Beta(1)) })] - #[case(quote!(ignore = "v1"), Version { major: 1, level: None })] - fn from_meta(#[case] input: proc_macro2::TokenStream, #[case] expected: Version) { - let meta = parse_meta(input).expect("valid attribute tokens"); - let version = Version::from_meta(&meta).expect("version must parse from attribute"); - assert_eq!(version, expected); - } } diff --git a/crates/k8s-version/src/version/serde.rs b/crates/k8s-version/src/version/serde.rs new file mode 100644 index 000000000..62401334f --- /dev/null +++ b/crates/k8s-version/src/version/serde.rs @@ -0,0 +1,40 @@ +use std::str::FromStr; + +use serde::{Deserialize, Serialize, de::Visitor}; + +use crate::Version; + +impl<'de> Deserialize<'de> for Version { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct VersionVisitor; + + impl<'de> Visitor<'de> for VersionVisitor { + type Value = Version; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "a valid Kubernetes API version") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + Version::from_str(v).map_err(serde::de::Error::custom) + } + } + + deserializer.deserialize_str(VersionVisitor) + } +} + +impl Serialize for Version { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} From 98d8da684997a313d035ce34fd3dd10580fe007b Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 15:05:17 +0200 Subject: [PATCH 2/6] refactor(k8s-version): Move darling code into separate files --- crates/k8s-version/src/level/darling.rs | 34 +++++++++++++++++++++ crates/k8s-version/src/version/darling.rs | 37 +++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 crates/k8s-version/src/level/darling.rs create mode 100644 crates/k8s-version/src/version/darling.rs diff --git a/crates/k8s-version/src/level/darling.rs b/crates/k8s-version/src/level/darling.rs new file mode 100644 index 000000000..41aaad4f5 --- /dev/null +++ b/crates/k8s-version/src/level/darling.rs @@ -0,0 +1,34 @@ +use std::str::FromStr; + +use darling::FromMeta; + +use crate::Level; + +impl FromMeta for Level { + fn from_string(value: &str) -> darling::Result { + Self::from_str(value).map_err(darling::Error::custom) + } +} + +#[cfg(test)] +mod tests { + use quote::quote; + use rstest::rstest; + + use super::*; + + fn parse_meta(tokens: proc_macro2::TokenStream) -> ::std::result::Result { + let attribute: syn::Attribute = syn::parse_quote!(#[#tokens]); + Ok(attribute.meta) + } + + #[rstest] + #[case(quote!(ignore = "alpha12"), Level::Alpha(12))] + #[case(quote!(ignore = "alpha1"), Level::Alpha(1))] + #[case(quote!(ignore = "beta1"), Level::Beta(1))] + fn from_meta(#[case] input: proc_macro2::TokenStream, #[case] expected: Level) { + let meta = parse_meta(input).expect("valid attribute tokens"); + let version = Level::from_meta(&meta).expect("level must parse from attribute"); + assert_eq!(version, expected); + } +} diff --git a/crates/k8s-version/src/version/darling.rs b/crates/k8s-version/src/version/darling.rs new file mode 100644 index 000000000..3c2ae3216 --- /dev/null +++ b/crates/k8s-version/src/version/darling.rs @@ -0,0 +1,37 @@ +use std::str::FromStr; + +use darling::FromMeta; + +use crate::Version; + +impl FromMeta for Version { + fn from_string(value: &str) -> darling::Result { + Self::from_str(value).map_err(darling::Error::custom) + } +} + +#[cfg(test)] +mod tests { + use quote::quote; + use rstest::rstest; + + use super::*; + use crate::Level; + + fn parse_meta(tokens: proc_macro2::TokenStream) -> ::std::result::Result { + let attribute: syn::Attribute = syn::parse_quote!(#[#tokens]); + Ok(attribute.meta) + } + + #[cfg(feature = "darling")] + #[rstest] + #[case(quote!(ignore = "v1alpha12"), Version { major: 1, level: Some(Level::Alpha(12)) })] + #[case(quote!(ignore = "v1alpha1"), Version { major: 1, level: Some(Level::Alpha(1)) })] + #[case(quote!(ignore = "v1beta1"), Version { major: 1, level: Some(Level::Beta(1)) })] + #[case(quote!(ignore = "v1"), Version { major: 1, level: None })] + fn from_meta(#[case] input: proc_macro2::TokenStream, #[case] expected: Version) { + let meta = parse_meta(input).expect("valid attribute tokens"); + let version = Version::from_meta(&meta).expect("version must parse from attribute"); + assert_eq!(version, expected); + } +} From 8fd0c8f790631ef0fc0a53dc5f56e824c8d28552 Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 15:20:45 +0200 Subject: [PATCH 3/6] chore(k8s-version): Add changelog entry --- crates/k8s-version/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/k8s-version/CHANGELOG.md b/crates/k8s-version/CHANGELOG.md index 727bf0158..fa4f493c5 100644 --- a/crates/k8s-version/CHANGELOG.md +++ b/crates/k8s-version/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Add support for Deserialization and Deserialization via `serde`. This feature is enables via the + `serde` feature flag ([#1034]). + +[#1034]: https://github.com/stackabletech/operator-rs/pull/1034 + ## [0.1.2] - 2024-09-19 ### Changed From db25ac0d5931617b71aefbd1d1d4eb3454e4d182 Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 16:02:05 +0200 Subject: [PATCH 4/6] test(k8s-version): Add unit tests for (de)serialization --- Cargo.lock | 1 + crates/k8s-version/Cargo.toml | 1 + crates/k8s-version/src/api_version/serde.rs | 22 ++++++++++ .../src/{group/mod.rs => group.rs} | 24 +++++++++-- crates/k8s-version/src/group/serde.rs | 40 ------------------- crates/k8s-version/src/level/serde.rs | 20 ++++++++++ crates/k8s-version/src/version/serde.rs | 20 ++++++++++ 7 files changed, 85 insertions(+), 43 deletions(-) rename crates/k8s-version/src/{group/mod.rs => group.rs} (78%) delete mode 100644 crates/k8s-version/src/group/serde.rs diff --git a/Cargo.lock b/Cargo.lock index 8502754b6..0b6637a52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1658,6 +1658,7 @@ dependencies = [ "rstest", "rstest_reuse", "serde", + "serde_yaml", "snafu 0.8.5", "syn 2.0.101", ] diff --git a/crates/k8s-version/Cargo.toml b/crates/k8s-version/Cargo.toml index de550e5f5..5be8d3207 100644 --- a/crates/k8s-version/Cargo.toml +++ b/crates/k8s-version/Cargo.toml @@ -21,4 +21,5 @@ rstest.workspace = true rstest_reuse.workspace = true quote.workspace = true proc-macro2.workspace = true +serde_yaml.workspace = true syn.workspace = true diff --git a/crates/k8s-version/src/api_version/serde.rs b/crates/k8s-version/src/api_version/serde.rs index abacb0412..f9754c842 100644 --- a/crates/k8s-version/src/api_version/serde.rs +++ b/crates/k8s-version/src/api_version/serde.rs @@ -38,3 +38,25 @@ impl Serialize for ApiVersion { serializer.serialize_str(&self.to_string()) } } + +#[cfg(feature = "serde")] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialize() { + let _: ApiVersion = + serde_yaml::from_str("extensions.k8s.io/v1alpha1").expect("api version is valid"); + } + + #[test] + fn serialize() { + let api_version = + ApiVersion::from_str("extensions.k8s.io/v1alpha1").expect("api version is valid"); + assert_eq!( + "extensions.k8s.io/v1alpha1\n", + serde_yaml::to_string(&api_version).expect("api version must serialize") + ); + } +} diff --git a/crates/k8s-version/src/group/mod.rs b/crates/k8s-version/src/group.rs similarity index 78% rename from crates/k8s-version/src/group/mod.rs rename to crates/k8s-version/src/group.rs index b2f7ff47c..ee15f9911 100644 --- a/crates/k8s-version/src/group/mod.rs +++ b/crates/k8s-version/src/group.rs @@ -3,9 +3,6 @@ use std::{fmt, ops::Deref, str::FromStr, sync::LazyLock}; use regex::Regex; use snafu::{Snafu, ensure}; -#[cfg(feature = "serde")] -mod serde; - const MAX_GROUP_LENGTH: usize = 253; static API_GROUP_REGEX: LazyLock = LazyLock::new(|| { @@ -38,6 +35,7 @@ pub enum ParseGroupError { /// ### See /// /// - +#[cfg_attr(feature = "serde", derive(::serde::Deserialize, ::serde::Serialize))] #[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd)] pub struct Group(String); @@ -66,3 +64,23 @@ impl Deref for Group { &self.0 } } + +#[cfg(feature = "serde")] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialize() { + let _: Group = serde_yaml::from_str("extensions.k8s.io").expect("group is valid"); + } + + #[test] + fn serialize() { + let group = Group("extensions.k8s.io".into()); + assert_eq!( + "extensions.k8s.io\n", + serde_yaml::to_string(&group).expect("group must serialize") + ); + } +} diff --git a/crates/k8s-version/src/group/serde.rs b/crates/k8s-version/src/group/serde.rs deleted file mode 100644 index 2fd8dd14e..000000000 --- a/crates/k8s-version/src/group/serde.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::str::FromStr; - -use serde::{Deserialize, Serialize, de::Visitor}; - -use crate::Group; - -impl<'de> Deserialize<'de> for Group { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct GroupVisitor; - - impl<'de> Visitor<'de> for GroupVisitor { - type Value = Group; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(formatter, "a valid Kubernetes API group") - } - - fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, - { - Group::from_str(v).map_err(serde::de::Error::custom) - } - } - - deserializer.deserialize_str(GroupVisitor) - } -} - -impl Serialize for Group { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_str(&self) - } -} diff --git a/crates/k8s-version/src/level/serde.rs b/crates/k8s-version/src/level/serde.rs index 75b33db50..59bda5702 100644 --- a/crates/k8s-version/src/level/serde.rs +++ b/crates/k8s-version/src/level/serde.rs @@ -38,3 +38,23 @@ impl Serialize for Level { serializer.serialize_str(&self.to_string()) } } + +#[cfg(feature = "serde")] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialize() { + let _: Level = serde_yaml::from_str("alpha1").expect("level is valid"); + } + + #[test] + fn serialize() { + let api_version = Level::from_str("alpha1").expect("level is valid"); + assert_eq!( + "alpha1\n", + serde_yaml::to_string(&api_version).expect("level must serialize") + ); + } +} diff --git a/crates/k8s-version/src/version/serde.rs b/crates/k8s-version/src/version/serde.rs index 62401334f..88c7d98c3 100644 --- a/crates/k8s-version/src/version/serde.rs +++ b/crates/k8s-version/src/version/serde.rs @@ -38,3 +38,23 @@ impl Serialize for Version { serializer.serialize_str(&self.to_string()) } } + +#[cfg(feature = "serde")] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialize() { + let _: Version = serde_yaml::from_str("v1alpha1").expect("version is valid"); + } + + #[test] + fn serialize() { + let api_version = Version::from_str("v1alpha1").expect("version is valid"); + assert_eq!( + "v1alpha1\n", + serde_yaml::to_string(&api_version).expect("version must serialize") + ); + } +} From 78dd66501e3c19425cb8f71def4c1586f6d84782 Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 16:03:00 +0200 Subject: [PATCH 5/6] chore(k8s-version): Correct typos in changelog --- crates/k8s-version/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/k8s-version/CHANGELOG.md b/crates/k8s-version/CHANGELOG.md index fa4f493c5..45817b049 100644 --- a/crates/k8s-version/CHANGELOG.md +++ b/crates/k8s-version/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Added -- Add support for Deserialization and Deserialization via `serde`. This feature is enables via the +- Add support for Serialization and Deserialization via `serde`. This feature is enabled via the `serde` feature flag ([#1034]). [#1034]: https://github.com/stackabletech/operator-rs/pull/1034 From 65d2845a22260328888a5bee2fc43e07d2668dd9 Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 15 May 2025 16:20:20 +0200 Subject: [PATCH 6/6] chore: Apply suggestion --- crates/k8s-version/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/k8s-version/CHANGELOG.md b/crates/k8s-version/CHANGELOG.md index 45817b049..85e828ddf 100644 --- a/crates/k8s-version/CHANGELOG.md +++ b/crates/k8s-version/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Added -- Add support for Serialization and Deserialization via `serde`. This feature is enabled via the +- Add support for serialization and deserialization via `serde`. This feature is enabled via the `serde` feature flag ([#1034]). [#1034]: https://github.com/stackabletech/operator-rs/pull/1034