diff --git a/kube-core/src/object.rs b/kube-core/src/object.rs index 2ebd3e634..6494da899 100644 --- a/kube-core/src/object.rs +++ b/kube-core/src/object.rs @@ -16,13 +16,13 @@ use std::borrow::Cow; /// and is generally produced from list/watch/delete collection queries on an [`Resource`](super::Resource). /// /// This is almost equivalent to [`k8s_openapi::List`](k8s_openapi::List), but iterable. -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct ObjectList where T: Clone, { /// The type fields, always present - #[serde(flatten, default)] + #[serde(flatten, deserialize_with = "deserialize_v1_list_as_default")] pub types: TypeMeta, /// ListMeta - only really used for its `resourceVersion` @@ -38,6 +38,17 @@ where pub items: Vec, } +fn deserialize_v1_list_as_default<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let meta = Option::::deserialize(deserializer)?; + Ok(meta.unwrap_or(TypeMeta { + api_version: "v1".to_owned(), + kind: "List".to_owned(), + })) +} + fn deserialize_null_as_default<'de, D, T>(deserializer: D) -> Result where T: Default + Deserialize<'de>, @@ -394,4 +405,24 @@ mod test { assert!(mypod.status.is_none()); assert!(mypod.spec.is_none()); } + + #[test] + fn k8s_object_list_default_types() { + use k8s_openapi::api::core::v1::Pod; + + let raw_value = serde_json::json!({ + "metadata": { + "resourceVersion": "" + }, + "items": [] + }); + let pod_list: ObjectList = serde_json::from_value(raw_value).unwrap(); + assert_eq!( + TypeMeta { + api_version: "v1".to_owned(), + kind: "List".to_owned(), + }, + pod_list.types, + ); + } }