-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change
WatchEvent::Bookmark
to store the resource version directly …
…instead of the full object. In some cases, the API server sends a BOOKMARK watch event that can't be successfully deserialized as the resource type. The example in #70 is of a watch event for pods where the `spec.containers` field is `null`, even though the spec requires that `containers` be non-null. Since the only point of bookmark events is to carry a resource version, this change makes it so that the deserializer only looks for the `metadata.resourceVersion` field, in addition to the `apiVersion` and `kind` fields like before. Apart from changing the definition of the `WatchEvent::Bookmark` variant, this change also adds a bound to the type parameter of `WatchEvent` - it must now also implement `k8s_openapi::Resource` since its API_VERSION and KIND are still needed to validate the bookmark object. Fixes #70
- Loading branch information
Showing
22 changed files
with
1,166 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
186 changes: 186 additions & 0 deletions
186
k8s-openapi-codegen-common/templates/watch_event_bookmark_object.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
|
||
#[derive(Debug, PartialEq)] | ||
struct BookmarkObject<'a, T> {{ | ||
metadata: BookmarkObjectMeta<'a>, | ||
_resource: std::marker::PhantomData<T>, | ||
}} | ||
|
||
#[derive(Debug, PartialEq)] | ||
struct BookmarkObjectMeta<'a> {{ | ||
resource_version: std::borrow::Cow<'a, str>, | ||
}} | ||
|
||
impl<'de, T> serde::Deserialize<'de> for BookmarkObject<'static, T> where T: {crate_root}::Resource {{ | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {{ | ||
#[allow(non_camel_case_types)] | ||
enum Field {{ | ||
Key_api_version, | ||
Key_kind, | ||
Key_metadata, | ||
Other, | ||
}} | ||
|
||
impl<'de> serde::Deserialize<'de> for Field {{ | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {{ | ||
struct Visitor; | ||
|
||
impl<'de> serde::de::Visitor<'de> for Visitor {{ | ||
type Value = Field; | ||
|
||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{ | ||
f.write_str("field identifier") | ||
}} | ||
|
||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {{ | ||
Ok(match v {{ | ||
"apiVersion" => Field::Key_api_version, | ||
"kind" => Field::Key_kind, | ||
"metadata" => Field::Key_metadata, | ||
_ => Field::Other, | ||
}}) | ||
}} | ||
}} | ||
|
||
deserializer.deserialize_identifier(Visitor) | ||
}} | ||
}} | ||
|
||
struct Visitor<T>(std::marker::PhantomData<T>); | ||
|
||
impl<'de, T> serde::de::Visitor<'de> for Visitor<T> where T: {crate_root}::Resource {{ | ||
type Value = BookmarkObject<'static, T>; | ||
|
||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{ | ||
f.write_str(<T as {crate_root}::Resource>::KIND) | ||
}} | ||
|
||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {{ | ||
let mut value_metadata: Option<BookmarkObjectMeta<'static>> = None; | ||
|
||
while let Some(key) = serde::de::MapAccess::next_key::<Field>(&mut map)? {{ | ||
match key {{ | ||
Field::Key_api_version => {{ | ||
let value_api_version: String = serde::de::MapAccess::next_value(&mut map)?; | ||
if value_api_version != <T as {crate_root}::Resource>::API_VERSION {{ | ||
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(&value_api_version), &<T as {crate_root}::Resource>::API_VERSION)); | ||
}} | ||
}}, | ||
Field::Key_kind => {{ | ||
let value_kind: String = serde::de::MapAccess::next_value(&mut map)?; | ||
if value_kind != <T as {crate_root}::Resource>::KIND {{ | ||
return Err(serde::de::Error::invalid_value(serde::de::Unexpected::Str(&value_kind), &<T as {crate_root}::Resource>::KIND)); | ||
}} | ||
}}, | ||
Field::Key_metadata => value_metadata = serde::de::MapAccess::next_value(&mut map)?, | ||
Field::Other => {{ let _: serde::de::IgnoredAny = serde::de::MapAccess::next_value(&mut map)?; }}, | ||
}} | ||
}} | ||
|
||
Ok(BookmarkObject {{ | ||
metadata: value_metadata.ok_or_else(|| serde::de::Error::missing_field("metadata"))?, | ||
_resource: Default::default() | ||
}}) | ||
}} | ||
}} | ||
|
||
deserializer.deserialize_struct( | ||
<T as {crate_root}::Resource>::KIND, | ||
&[ | ||
"apiVersion", | ||
"kind", | ||
"metadata", | ||
], | ||
Visitor(Default::default()), | ||
) | ||
}} | ||
}} | ||
|
||
impl<'de> serde::Deserialize<'de> for BookmarkObjectMeta<'static> {{ | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {{ | ||
#[allow(non_camel_case_types)] | ||
enum Field {{ | ||
Key_resource_version, | ||
Other, | ||
}} | ||
|
||
impl<'de> serde::Deserialize<'de> for Field {{ | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {{ | ||
struct Visitor; | ||
|
||
impl<'de> serde::de::Visitor<'de> for Visitor {{ | ||
type Value = Field; | ||
|
||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{ | ||
f.write_str("field identifier") | ||
}} | ||
|
||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {{ | ||
Ok(match v {{ | ||
"resourceVersion" => Field::Key_resource_version, | ||
_ => Field::Other, | ||
}}) | ||
}} | ||
}} | ||
|
||
deserializer.deserialize_identifier(Visitor) | ||
}} | ||
}} | ||
|
||
struct Visitor; | ||
|
||
impl<'de> serde::de::Visitor<'de> for Visitor {{ | ||
type Value = BookmarkObjectMeta<'static>; | ||
|
||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {{ | ||
f.write_str("ObjectMeta") | ||
}} | ||
|
||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {{ | ||
let mut value_resource_version: Option<String> = None; | ||
|
||
while let Some(key) = serde::de::MapAccess::next_key::<Field>(&mut map)? {{ | ||
match key {{ | ||
Field::Key_resource_version => value_resource_version = serde::de::MapAccess::next_value(&mut map)?, | ||
Field::Other => {{ let _: serde::de::IgnoredAny = serde::de::MapAccess::next_value(&mut map)?; }}, | ||
}} | ||
}} | ||
|
||
Ok(BookmarkObjectMeta {{ | ||
resource_version: std::borrow::Cow::Owned(value_resource_version.ok_or_else(|| serde::de::Error::missing_field("resourceVersion"))?), | ||
}}) | ||
}} | ||
}} | ||
|
||
deserializer.deserialize_struct( | ||
"ObjectMeta", | ||
&[ | ||
"resourceVersion", | ||
], | ||
Visitor, | ||
) | ||
}} | ||
}} | ||
|
||
impl<'a, T> serde::Serialize for BookmarkObject<'a, T> where T: {crate_root}::Resource {{ | ||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {{ | ||
let mut state = serializer.serialize_struct( | ||
<T as {crate_root}::Resource>::KIND, | ||
3, | ||
)?; | ||
serde::ser::SerializeStruct::serialize_field(&mut state, "apiVersion", <T as {crate_root}::Resource>::API_VERSION)?; | ||
serde::ser::SerializeStruct::serialize_field(&mut state, "kind", <T as {crate_root}::Resource>::KIND)?; | ||
serde::ser::SerializeStruct::serialize_field(&mut state, "metadata", &self.metadata)?; | ||
serde::ser::SerializeStruct::end(state) | ||
}} | ||
}} | ||
|
||
impl<'a> serde::Serialize for BookmarkObjectMeta<'a> {{ | ||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {{ | ||
let mut state = serializer.serialize_struct( | ||
"ObjectMeta", | ||
1, | ||
)?; | ||
serde::ser::SerializeStruct::serialize_field(&mut state, "resourceVersion", &self.resource_version)?; | ||
serde::ser::SerializeStruct::end(state) | ||
}} | ||
}} |
Oops, something went wrong.