Skip to content

Commit

Permalink
Fixed definitions with no "type" property to be emitted as newtypes a…
Browse files Browse the repository at this point in the history
…round `serde_json::Value`

... instead of empty structs.

Fixes the codegen for
`io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresourceStatus`
and
`io.k8s.apimachinery.pkg.apis.meta.v1.Patch`
  • Loading branch information
Arnavion committed Mar 26, 2019
1 parent 51d6f69 commit 79185b3
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 524 deletions.
6 changes: 3 additions & 3 deletions k8s-openapi-codegen/src/fixups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ pub(crate) mod json_ty {
pub(crate) fn json_schema_props_or_array(spec: &mut crate::swagger20::Spec) -> Result<(), crate::Error> {
for (definition_path, definition) in &mut spec.definitions {
if &**definition_path == "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrArray" {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::Any) = definition.kind {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrArray) = definition.kind {
}
else {
definition.kind = crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrArray);
Expand All @@ -211,7 +211,7 @@ pub(crate) mod json_ty {
pub(crate) fn json_schema_props_or_bool(spec: &mut crate::swagger20::Spec) -> Result<(), crate::Error> {
for (definition_path, definition) in &mut spec.definitions {
if &**definition_path == "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrBool" {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::Any) = definition.kind {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrBool) = definition.kind {
}
else {
definition.kind = crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrBool);
Expand All @@ -228,7 +228,7 @@ pub(crate) mod json_ty {
pub(crate) fn json_schema_props_or_string_array(spec: &mut crate::swagger20::Spec) -> Result<(), crate::Error> {
for (definition_path, definition) in &mut spec.definitions {
if &**definition_path == "io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.JSONSchemaPropsOrStringArray" {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::Any) = definition.kind {
if let crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrStringArray) = definition.kind {
}
else {
definition.kind = crate::swagger20::SchemaKind::Ty(crate::swagger20::Type::JSONSchemaPropsOrStringArray);
Expand Down
3 changes: 0 additions & 3 deletions k8s-openapi-codegen/src/supported_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ impl SupportedVersion {

SupportedVersion::V1_11 => &[
crate::fixups::deployment_rollback_create_response_type,
crate::fixups::json_ty::json,
crate::fixups::json_ty::json_schema_props_or_array,
crate::fixups::json_ty::json_schema_props_or_bool,
crate::fixups::json_ty::json_schema_props_or_string_array,
Expand All @@ -118,7 +117,6 @@ impl SupportedVersion {

SupportedVersion::V1_12 => &[
crate::fixups::connect_options_gvk,
crate::fixups::json_ty::json,
crate::fixups::json_ty::json_schema_props_or_array,
crate::fixups::json_ty::json_schema_props_or_bool,
crate::fixups::json_ty::json_schema_props_or_string_array,
Expand All @@ -131,7 +129,6 @@ impl SupportedVersion {

SupportedVersion::V1_13 => &[
crate::fixups::connect_options_gvk,
crate::fixups::json_ty::json,
crate::fixups::json_ty::json_schema_props_or_array,
crate::fixups::json_ty::json_schema_props_or_bool,
crate::fixups::json_ty::json_schema_props_or_string_array,
Expand Down
26 changes: 18 additions & 8 deletions k8s-openapi-codegen/src/swagger20/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ impl<'de> serde::Deserialize<'de> for Schema {
#[serde(rename = "x-kubernetes-group-version-kind")]
kubernetes_group_kind_versions: Option<Vec<super::KubernetesGroupKindVersion>>,

#[serde(default)]
properties: std::collections::BTreeMap<PropertyName, Schema>,
properties: Option<std::collections::BTreeMap<PropertyName, Schema>>,

#[serde(rename = "$ref")]
ref_path: Option<RefPath>,
Expand All @@ -125,12 +124,27 @@ impl<'de> serde::Deserialize<'de> for Schema {
ty: Option<String>,
}

let value: InnerSchema = serde::Deserialize::deserialize(deserializer)?;
let mut value: InnerSchema = serde::Deserialize::deserialize(deserializer)?;

let kind =
if let Some(ref_path) = value.ref_path {
SchemaKind::Ref(ref_path)
}
else if let Some(properties) = value.properties.take() {
// Starting from 1.14, the spec sets type=object for all types with properties.
// Earlier specs did not set it at all.
if let Some(ty) = value.ty.take() {
if ty != "object" {
return Err(serde::de::Error::custom(format!("schema has properties but not type=object {:?}", value)));
}
}

let required: std::collections::HashSet<_> = value.required.into_iter().collect();
SchemaKind::Properties(properties.into_iter().map(|(name, schema)| {
let required = required.contains(&name);
(name, (schema, required))
}).collect())
}
else if let Some(ty) = value.ty {
SchemaKind::Ty(Type::parse::<D>(
&ty,
Expand All @@ -140,11 +154,7 @@ impl<'de> serde::Deserialize<'de> for Schema {
)?)
}
else {
let required: std::collections::HashSet<_> = value.required.into_iter().collect();
SchemaKind::Properties(value.properties.into_iter().map(|(name, schema)| {
let required = required.contains(&name);
(name, (schema, required))
}).collect())
SchemaKind::Ty(Type::Any)
};

Ok(Schema {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,30 @@

/// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources. Status is represented by the `.status` JSON path inside of a CustomResource. When set, * exposes a /status subresource for the custom resource * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CustomResourceSubresourceStatus {
}
pub struct CustomResourceSubresourceStatus(pub serde_json::Value);

impl<'de> serde::Deserialize<'de> for CustomResourceSubresourceStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
enum Field {
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 {
write!(f, "field identifier")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(match v {
_ => Field::Other,
})
}
}

deserializer.deserialize_identifier(Visitor)
}
}

struct Visitor;

impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = CustomResourceSubresourceStatus;

fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "struct CustomResourceSubresourceStatus")
write!(f, "CustomResourceSubresourceStatus")
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {

while let Some(key) = serde::de::MapAccess::next_key::<Field>(&mut map)? {
match key {
Field::Other => { let _: serde::de::IgnoredAny = serde::de::MapAccess::next_value(&mut map)?; },
}
}

Ok(CustomResourceSubresourceStatus {
})
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: serde::Deserializer<'de> {
Ok(CustomResourceSubresourceStatus(serde::Deserialize::deserialize(deserializer)?))
}
}

deserializer.deserialize_struct(
"CustomResourceSubresourceStatus",
&[
],
Visitor,
)
deserializer.deserialize_newtype_struct("CustomResourceSubresourceStatus", Visitor)
}
}

impl serde::Serialize for CustomResourceSubresourceStatus {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
let state = serializer.serialize_struct(
"CustomResourceSubresourceStatus",
0,
)?;
serde::ser::SerializeStruct::end(state)
serializer.serialize_newtype_struct("CustomResourceSubresourceStatus", &self.0)
}
}
57 changes: 6 additions & 51 deletions src/v1_10/apimachinery/pkg/apis/meta/v1/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,30 @@

/// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Patch {
}
pub struct Patch(pub serde_json::Value);

impl<'de> serde::Deserialize<'de> for Patch {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
enum Field {
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 {
write!(f, "field identifier")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(match v {
_ => Field::Other,
})
}
}

deserializer.deserialize_identifier(Visitor)
}
}

struct Visitor;

impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Patch;

fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "struct Patch")
write!(f, "Patch")
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {

while let Some(key) = serde::de::MapAccess::next_key::<Field>(&mut map)? {
match key {
Field::Other => { let _: serde::de::IgnoredAny = serde::de::MapAccess::next_value(&mut map)?; },
}
}

Ok(Patch {
})
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: serde::Deserializer<'de> {
Ok(Patch(serde::Deserialize::deserialize(deserializer)?))
}
}

deserializer.deserialize_struct(
"Patch",
&[
],
Visitor,
)
deserializer.deserialize_newtype_struct("Patch", Visitor)
}
}

impl serde::Serialize for Patch {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
let state = serializer.serialize_struct(
"Patch",
0,
)?;
serde::ser::SerializeStruct::end(state)
serializer.serialize_newtype_struct("Patch", &self.0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,30 @@

/// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources. Status is represented by the `.status` JSON path inside of a CustomResource. When set, * exposes a /status subresource for the custom resource * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
#[derive(Clone, Debug, Default, PartialEq)]
pub struct CustomResourceSubresourceStatus {
}
pub struct CustomResourceSubresourceStatus(pub serde_json::Value);

impl<'de> serde::Deserialize<'de> for CustomResourceSubresourceStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
#[allow(non_camel_case_types)]
enum Field {
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 {
write!(f, "field identifier")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error {
Ok(match v {
_ => Field::Other,
})
}
}

deserializer.deserialize_identifier(Visitor)
}
}

struct Visitor;

impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = CustomResourceSubresourceStatus;

fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "struct CustomResourceSubresourceStatus")
write!(f, "CustomResourceSubresourceStatus")
}

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> where A: serde::de::MapAccess<'de> {

while let Some(key) = serde::de::MapAccess::next_key::<Field>(&mut map)? {
match key {
Field::Other => { let _: serde::de::IgnoredAny = serde::de::MapAccess::next_value(&mut map)?; },
}
}

Ok(CustomResourceSubresourceStatus {
})
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: serde::Deserializer<'de> {
Ok(CustomResourceSubresourceStatus(serde::Deserialize::deserialize(deserializer)?))
}
}

deserializer.deserialize_struct(
"CustomResourceSubresourceStatus",
&[
],
Visitor,
)
deserializer.deserialize_newtype_struct("CustomResourceSubresourceStatus", Visitor)
}
}

impl serde::Serialize for CustomResourceSubresourceStatus {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
let state = serializer.serialize_struct(
"CustomResourceSubresourceStatus",
0,
)?;
serde::ser::SerializeStruct::end(state)
serializer.serialize_newtype_struct("CustomResourceSubresourceStatus", &self.0)
}
}
Loading

0 comments on commit 79185b3

Please sign in to comment.