Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions crates/stackable-versioned-macros/src/codegen/item/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl VersionedField {
Direction::Downgrade => {
let next_change = changes.get_expect(&next_version.inner);

let yaml_serde_path = &*mod_gen_ctx.crates.yaml_serde;
let serde_json_path = &*mod_gen_ctx.crates.serde_json;
let versioned_path = &*mod_gen_ctx.crates.versioned;

match next_change {
Expand All @@ -327,7 +327,7 @@ impl VersionedField {
Some(quote! {
upgrades.push(#versioned_path::ChangedValue {
json_path: #json_path_ident,
value: #yaml_serde_path::to_value(&#from_struct_ident.#ident).unwrap(),
value: #serde_json_path::to_value(&#from_struct_ident.#ident).unwrap(),
});
})
}
Expand All @@ -349,7 +349,7 @@ impl VersionedField {
// for applying a tracked value.
let changes = self.changes.as_ref()?;

let yaml_serde_path = &*mod_gen_ctx.crates.yaml_serde;
let serde_json_path = &*mod_gen_ctx.crates.serde_json;
let versioned_path = &*mod_gen_ctx.crates.versioned;

match direction {
Expand All @@ -368,7 +368,7 @@ impl VersionedField {
Some(quote! {
if let Some(#versioned_path::ChangedValue { value, .. }) = upgrades.extract_first_if(|u| u.json_path == #json_path_ident) {
// TODO (@Techassi): Switch to serde_json
spec.#ident = #yaml_serde_path::from_value(value).expect(#expect_message);
spec.#ident = #serde_json_path::from_value(value).expect(#expect_message);
}
})
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions crates/stackable-versioned/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,19 @@ All notable changes to this project will be documented in this file.
- Add public `ExtractIfExt` trait ([#13006]).
- Re-add support for generics in tracking impls ([#1304]).

### Changed

- BREAKING: `stackable_versioned::ChangedValue`'s `value` field type is now `serde_json::Value` instead
of `yaml_serde::Value` ([#1307]).

### Fixed

- Fix how the generated code (de)serializes enums in the tracking status ([#1307]).
- Correctly handle tracked per-version changes across multiple containers ([#1306]).

[#1304]: https://github.com/stackabletech/operator-rs/pull/1304
[#1306]: https://github.com/stackabletech/operator-rs/pull/1306
[#1307]: https://github.com/stackabletech/operator-rs/pull/1307

## [0.13.0] - 2026-10-14

Expand Down
1 change: 0 additions & 1 deletion crates/stackable-versioned/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ kube.workspace = true
schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
yaml_serde.workspace = true
snafu.workspace = true

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/stackable-versioned/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub struct ChangedValue {

/// The value to be used when upgrading or downgrading the custom resource.
#[schemars(schema_with = "raw_object_schema")]
pub value: yaml_serde::Value,
pub value: serde_json::Value,
}

// TODO (@Techassi): Think about where this should live. Basically this already exists in
Expand Down
96 changes: 48 additions & 48 deletions crates/stackable-versioned/tests/person.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ pub mod versioned {
#[versioned(added(since = "v2"), changed(since = "v3", from_type = "Gender"))]
gender: String,

// FIXME (@Techassi): This currently breaks because of how enum are serialized by default
// by yaml_serde (singleton map)
// #[versioned(added(since = "v1alpha2"), nested)]
#[versioned(nested)]
// TODO (@Techassi): Dealing with Default here is kinda meh UX wise. What would really help
// is enabling per-container versioning and maybe the ability to place impl blocks in here
// for automatic implementations for all versions of a container.
#[versioned(added(since = "v1alpha2", default = default_relationship), nested)]
relationship: Relationship,

#[versioned(nested)]
Expand Down Expand Up @@ -115,22 +115,62 @@ pub mod versioned {
}
}

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct PersonStatus {
pub alive: bool,
}

impl Default for PersonStatus {
fn default() -> Self {
Self { alive: true }
}
}

#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub enum Gender {
#[default]
Unknown,
Male,
Female,
}

impl From<Gender> 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<String> for Gender {
fn from(value: String) -> Self {
match value.as_str() {
"Male" => Self::Male,
"Female" => Self::Female,
_ => Self::Unknown,
}
}
}

fn default_relationship() -> v1alpha2::Relationship {
v1alpha2::Relationship::Other {}
}

#[cfg(test)]
impl stackable_versioned::test_utils::RoundtripTestData for v1alpha1::PersonSpec {
fn roundtrip_test_data() -> Vec<Self> {
vec![
Self {
username: "jdoe".to_string(),
relationship: v1alpha1::Relationship::Married(v1alpha1::Married {
with: "Jane Doe".into(),
}),
socials: v1alpha1::Socials {
email: "jdoe@example.com".to_owned(),
},
},
Self {
username: String::new(),
relationship: v1alpha1::Relationship::Single {},
socials: v1alpha1::Socials {
email: String::new(),
},
Expand Down Expand Up @@ -185,43 +225,3 @@ impl stackable_versioned::test_utils::RoundtripTestData for v3::PersonSpec {
]
}
}

#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
pub struct PersonStatus {
pub alive: bool,
}

impl Default for PersonStatus {
fn default() -> Self {
Self { alive: true }
}
}

#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "PascalCase")]
pub enum Gender {
#[default]
Unknown,
Male,
Female,
}

impl From<Gender> 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<String> for Gender {
fn from(value: String) -> Self {
match value.as_str() {
"Male" => Self::Male,
"Female" => Self::Female,
_ => Self::Unknown,
}
}
}
Loading
Loading