Skip to content

Commit

Permalink
Avoid characters in schema name that are invalid as ref
Browse files Browse the repository at this point in the history
  • Loading branch information
waltronix committed Nov 6, 2024
1 parent 9f86400 commit 98bcdb7
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 24 deletions.
23 changes: 13 additions & 10 deletions serde_with/src/schemars_0_8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ pub trait JsonSchemaAs<T: ?Sized> {
/// The name of the generated JSON Schema.
///
/// This is used as the title for root schemas, and the key within the root's `definitions` property for sub-schemas.
///
/// As the schema name is used as as part of `$ref` it has to be a valid URI path segment according to
/// [RFC 3986 Section-3](https://datatracker.ietf.org/doc/html/rfc3986#section-3).
fn schema_name() -> String;

/// Returns a string that uniquely identifies the schema produced by this type.
Expand Down Expand Up @@ -536,11 +539,11 @@ where
T: JsonSchema,
{
fn schema_name() -> String {
std::format!("EnumMap<{}>", T::schema_name())
std::format!("EnumMap({})", T::schema_name())
}

fn schema_id() -> Cow<'static, str> {
std::format!("serde_with::EnumMap<{}>", T::schema_id()).into()
std::format!("serde_with::EnumMap({})", T::schema_id()).into()
}

// We generate the schema here by going through all the variants of the
Expand Down Expand Up @@ -727,12 +730,12 @@ where
TA: JsonSchemaAs<T>,
{
fn schema_name() -> String {
std::format!("KeyValueMap<{}>", <WrapSchema<T, TA>>::schema_name())
std::format!("KeyValueMap({})", <WrapSchema<T, TA>>::schema_name())
}

fn schema_id() -> Cow<'static, str> {
std::format!(
"serde_with::KeyValueMap<{}>",
"serde_with::KeyValueMap({})",
<WrapSchema<T, TA>>::schema_id()
)
.into()
Expand Down Expand Up @@ -800,14 +803,14 @@ where
{
fn schema_name() -> String {
std::format!(
"OneOrMany<{}, PreferOne>",
"OneOrMany({},PreferOne)",
<WrapSchema<T, TA>>::schema_name()
)
}

fn schema_id() -> Cow<'static, str> {
std::format!(
"serde_with::OneOrMany<{}, PreferOne>",
"serde_with::OneOrMany({},PreferOne)",
<WrapSchema<T, TA>>::schema_id()
)
.into()
Expand Down Expand Up @@ -896,9 +899,9 @@ macro_rules! schema_for_pickfirst {
fn schema_name() -> String {
std::format!(
concat!(
"PickFirst<(",
"PickFirst(",
$( "{", stringify!($param), "}", )+
")>"
")"
),
$( $param = <WrapSchema<T, $param>>::schema_name(), )+
)
Expand All @@ -907,9 +910,9 @@ macro_rules! schema_for_pickfirst {
fn schema_id() -> Cow<'static, str> {
std::format!(
concat!(
"serde_with::PickFirst<(",
"serde_with::PickFirst(",
$( "{", stringify!($param), "}", )+
")>"
")"
),
$( $param = <WrapSchema<T, $param>>::schema_id(), )+
)
Expand Down
8 changes: 8 additions & 0 deletions serde_with/tests/schemars_0_8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,14 @@ mod snapshots {
}
}

pickfirst_nested {
#[serde(transparent)]
struct Test {
#[serde_as(as = "OneOrMany<PickFirst<(_, DisplayFromStr)>>")]
optional_value: Vec<u32>
}
}

one_or_many_nested {
struct Test {
#[serde_as(as = "Option<OneOrMany<_>>")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"description": "Will emit matching schemars attribute",
"allOf": [
{
"$ref": "#/definitions/PickFirst<(uint32String)>"
"$ref": "#/definitions/PickFirst(uint32String)"
}
]
},
Expand All @@ -44,7 +44,7 @@
}
},
"definitions": {
"PickFirst<(uint32String)>": {
"PickFirst(uint32String)": {
"anyOf": [
{
"type": "integer",
Expand Down
4 changes: 2 additions & 2 deletions serde_with/tests/schemars_0_8/snapshots/enum_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
],
"properties": {
"data": {
"$ref": "#/definitions/EnumMap<Mappable>"
"$ref": "#/definitions/EnumMap(Mappable)"
}
},
"definitions": {
"EnumMap<Mappable>": {
"EnumMap(Mappable)": {
"type": "object",
"properties": {
"A": {
Expand Down
4 changes: 2 additions & 2 deletions serde_with/tests/schemars_0_8/snapshots/key_value_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
],
"properties": {
"data": {
"$ref": "#/definitions/KeyValueMap<KvMapData>"
"$ref": "#/definitions/KeyValueMap(KvMapData)"
}
},
"definitions": {
"KeyValueMap<KvMapData>": {
"KeyValueMap(KvMapData)": {
"type": "object",
"additionalProperties": {
"type": "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
],
"properties": {
"data": {
"$ref": "#/definitions/KeyValueMap<KvMapEnum>"
"$ref": "#/definitions/KeyValueMap(KvMapEnum)"
}
},
"definitions": {
"KeyValueMap<KvMapEnum>": {
"KeyValueMap(KvMapEnum)": {
"type": "object",
"additionalProperties": {
"oneOf": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
],
"properties": {
"data": {
"$ref": "#/definitions/KeyValueMap<KvMapFlatten>"
"$ref": "#/definitions/KeyValueMap(KvMapFlatten)"
}
},
"definitions": {
"KeyValueMap<KvMapFlatten>": {
"KeyValueMap(KvMapFlatten)": {
"type": "object",
"additionalProperties": {
"type": "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"default": null,
"anyOf": [
{
"$ref": "#/definitions/OneOrMany<String, PreferOne>"
"$ref": "#/definitions/OneOrMany(String,PreferOne)"
},
{
"type": "null"
Expand All @@ -16,7 +16,7 @@
}
},
"definitions": {
"OneOrMany<String, PreferOne>": {
"OneOrMany(String,PreferOne)": {
"anyOf": [
{
"type": "string"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "OneOrMany<int32, PreferOne>",
"title": "OneOrMany(int32,PreferOne)",
"anyOf": [
{
"type": "integer",
Expand Down
2 changes: 1 addition & 1 deletion serde_with/tests/schemars_0_8/snapshots/pickfirst.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PickFirst<(uint32String)>",
"title": "PickFirst(uint32String)",
"anyOf": [
{
"type": "integer",
Expand Down
34 changes: 34 additions & 0 deletions serde_with/tests/schemars_0_8/snapshots/pickfirst_nested.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "OneOrMany(PickFirst(uint32String),PreferOne)",
"anyOf": [
{
"$ref": "#/definitions/PickFirst(uint32String)"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/PickFirst(uint32String)"
}
}
],
"definitions": {
"PickFirst(uint32String)": {
"anyOf": [
{
"type": "integer",
"format": "uint32",
"minimum": 0.0
},
{
"writeOnly": true,
"allOf": [
{
"type": "string"
}
]
}
]
}
}
}

0 comments on commit 98bcdb7

Please sign in to comment.