Improve schema naming for deriving on remote types

This commit is contained in:
Graham Esau 2019-12-27 15:37:59 +00:00
parent ea28450c30
commit 781f40b061
8 changed files with 36 additions and 23 deletions

View file

@ -16,6 +16,7 @@ use schemars::{schema_for, JsonSchema};
// This is just a copy of the remote data structure that Schemars can use to
// create a suitable JsonSchema impl.
#[derive(JsonSchema)]
#[serde(remote = "Duration")]
pub struct DurationDef {
pub secs: i64,
pub nanos: i32,

View file

@ -11,11 +11,11 @@
"type": "string"
},
"wall_time": {
"$ref": "#/definitions/DurationDef"
"$ref": "#/definitions/Duration"
}
},
"definitions": {
"DurationDef": {
"Duration": {
"type": "object",
"required": [
"nanos",

View file

@ -16,6 +16,7 @@ use schemars::{schema_for, JsonSchema};
// This is just a copy of the remote data structure that Schemars can use to
// create a suitable JsonSchema impl.
#[derive(JsonSchema)]
#[serde(remote = "Duration")]
pub struct DurationDef {
pub secs: i64,
pub nanos: i32,

View file

@ -11,11 +11,11 @@
"type": "string"
},
"wall_time": {
"$ref": "#/definitions/DurationDef"
"$ref": "#/definitions/Duration"
}
},
"definitions": {
"DurationDef": {
"Duration": {
"type": "object",
"required": [
"nanos",

View file

@ -14,7 +14,7 @@
"default": "0.000000000s",
"allOf": [
{
"$ref": "#/definitions/DurationDef"
"$ref": "#/definitions/Duration"
}
]
},
@ -25,16 +25,16 @@
},
"allOf": [
{
"$ref": "#/definitions/DurationDef"
"$ref": "#/definitions/Duration"
}
]
},
"wall_time": {
"$ref": "#/definitions/DurationDef"
"$ref": "#/definitions/Duration"
}
},
"definitions": {
"DurationDef": {
"Duration": {
"type": "object",
"required": [
"nanos",

View file

@ -10,7 +10,7 @@
],
"properties": {
"byte_or_bool2": {
"$ref": "#/definitions/OrDef_for_uint8_and_Boolean"
"$ref": "#/definitions/Or_for_uint8_and_Boolean"
},
"fake_map": {
"type": "object",
@ -22,14 +22,14 @@
}
},
"s": {
"$ref": "#/definitions/StrDef"
"$ref": "#/definitions/Str"
},
"unit_or_t2": {
"$ref": "#/definitions/OrDef_for_Null_and_int32"
"$ref": "#/definitions/Or_for_Null_and_int32"
}
},
"definitions": {
"OrDef_for_Null_and_int32": {
"Or_for_Null_and_int32": {
"anyOf": [
{
"type": "null"
@ -40,7 +40,7 @@
}
]
},
"OrDef_for_uint8_and_Boolean": {
"Or_for_uint8_and_Boolean": {
"anyOf": [
{
"type": "integer",
@ -52,7 +52,7 @@
}
]
},
"StrDef": {
"Str": {
"type": "string"
}
}

View file

@ -20,6 +20,7 @@ static SERDE_KEYWORDS: &[&str] = &[
"skip_serializing_if",
"skip_deserializing",
"flatten",
"remote",
// Special cases - `with`/`serialize_with` are passed to serde but not copied from schemars attrs to serde attrs.
// This is because we want to preserve any serde attribute's `serialize_with` value to determine whether the field's
// default value should be serialized. We also check the `with` value on schemars/serde attrs e.g. to support deriving

View file

@ -43,19 +43,22 @@ pub fn derive_json_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
let type_name = cont.ident;
let type_params: Vec<_> = cont.generics.type_params().map(|ty| &ty.ident).collect();
let schema_base_name = cont.attrs.name().deserialize_name();
let mut schema_base_name = cont.attrs.name().deserialize_name();
let schema_is_renamed = type_name != schema_base_name;
if !schema_is_renamed {
if let Some(path) = cont.attrs.remote() {
if let Some(segment) = path.segments.last() {
schema_base_name = segment.ident.to_string();
}
}
}
let schema_name = if type_params.is_empty() {
quote! {
#schema_base_name.to_owned()
}
} else if type_name == schema_base_name {
let mut schema_name_fmt = schema_base_name;
schema_name_fmt.push_str("_for_{}");
schema_name_fmt.push_str(&"_and_{}".repeat(type_params.len() - 1));
quote! {
format!(#schema_name_fmt #(,#type_params::schema_name())*)
}
} else {
} else if schema_is_renamed {
let mut schema_name_fmt = schema_base_name;
for tp in &type_params {
schema_name_fmt.push_str(&format!("{{{}:.0}}", tp));
@ -63,6 +66,13 @@ pub fn derive_json_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
quote! {
format!(#schema_name_fmt #(,#type_params=#type_params::schema_name())*)
}
} else {
let mut schema_name_fmt = schema_base_name;
schema_name_fmt.push_str("_for_{}");
schema_name_fmt.push_str(&"_and_{}".repeat(type_params.len() - 1));
quote! {
format!(#schema_name_fmt #(,#type_params::schema_name())*)
}
};
let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();