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 // This is just a copy of the remote data structure that Schemars can use to
// create a suitable JsonSchema impl. // create a suitable JsonSchema impl.
#[derive(JsonSchema)] #[derive(JsonSchema)]
#[serde(remote = "Duration")]
pub struct DurationDef { pub struct DurationDef {
pub secs: i64, pub secs: i64,
pub nanos: i32, pub nanos: i32,

View file

@ -11,11 +11,11 @@
"type": "string" "type": "string"
}, },
"wall_time": { "wall_time": {
"$ref": "#/definitions/DurationDef" "$ref": "#/definitions/Duration"
} }
}, },
"definitions": { "definitions": {
"DurationDef": { "Duration": {
"type": "object", "type": "object",
"required": [ "required": [
"nanos", "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 // This is just a copy of the remote data structure that Schemars can use to
// create a suitable JsonSchema impl. // create a suitable JsonSchema impl.
#[derive(JsonSchema)] #[derive(JsonSchema)]
#[serde(remote = "Duration")]
pub struct DurationDef { pub struct DurationDef {
pub secs: i64, pub secs: i64,
pub nanos: i32, pub nanos: i32,

View file

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

View file

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

View file

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

View file

@ -20,6 +20,7 @@ static SERDE_KEYWORDS: &[&str] = &[
"skip_serializing_if", "skip_serializing_if",
"skip_deserializing", "skip_deserializing",
"flatten", "flatten",
"remote",
// Special cases - `with`/`serialize_with` are passed to serde but not copied from schemars attrs to serde attrs. // 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 // 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 // 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_name = cont.ident;
let type_params: Vec<_> = cont.generics.type_params().map(|ty| &ty.ident).collect(); 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() { let schema_name = if type_params.is_empty() {
quote! { quote! {
#schema_base_name.to_owned() #schema_base_name.to_owned()
} }
} else if type_name == schema_base_name { } else if schema_is_renamed {
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 {
let mut schema_name_fmt = schema_base_name; let mut schema_name_fmt = schema_base_name;
for tp in &type_params { for tp in &type_params {
schema_name_fmt.push_str(&format!("{{{}:.0}}", tp)); 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! { quote! {
format!(#schema_name_fmt #(,#type_params=#type_params::schema_name())*) 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(); let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();