[BUG] [Rust] fails to compile discriminator if multiple oneOf definitions use the same key names
Created by: aeneasr
Bug Report Checklist
-
Have you provided a full/minimal spec to reproduce the issue? -
Have you validated the input using an OpenAPI validator (example)? -
Have you tested with the latest master to confirm the issue still exists? -
Have you searched for related issues/PRs? -
What's the actual output vs expected output? -
[Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
When using a spec which has a type that is a discriminator with multiple types, and at least two of those types have equal property names, the Rust generator fails to generate compilable code for that discriminator in cases where the conflicting key is also a type (e.g. an enum):
"uiNodeAttributes": {
"discriminator": {
"mapping": {
"a": "#/components/schemas/uiNodeAnchorAttributes",
"img": "#/components/schemas/uiNodeImageAttributes",
"input": "#/components/schemas/uiNodeInputAttributes",
"script": "#/components/schemas/uiNodeScriptAttributes",
"text": "#/components/schemas/uiNodeTextAttributes"
},
"propertyName": "node_type"
},
"oneOf": [
{
"$ref": "#/components/schemas/uiNodeInputAttributes"
},
{
"$ref": "#/components/schemas/uiNodeTextAttributes"
},
{
"$ref": "#/components/schemas/uiNodeImageAttributes"
},
{
"$ref": "#/components/schemas/uiNodeAnchorAttributes"
},
{
"$ref": "#/components/schemas/uiNodeScriptAttributes"
}
],
"title": "Attributes represents a list of attributes (e.g. `href=\"foo\"` for links)."
},
"uiNodeScriptAttributes": {
"properties": {
"async": {
"description": "The script async type",
"type": "boolean"
},
"crossorigin": {
"description": "The script cross origin policy",
"type": "string"
},
"id": {
"description": "A unique identifier",
"type": "string"
},
"integrity": {
"description": "The script's integrity hash",
"type": "string"
},
"node_type": {
"description": "NodeType represents this node's types. It is a mirror of `node.type` and\nis primarily used to allow compatibility with OpenAPI 3.0. In this struct it technically always is \"script\".",
"type": "string"
},
"nonce": {
"description": "Nonce for CSP\n\nA nonce you may want to use to improve your Content Security Policy.\nYou do not have to use this value but if you want to improve your CSP\npolicies you may use it. You can also choose to use your own nonce value!",
"type": "string"
},
"referrerpolicy": {
"description": "The script referrer policy",
"type": "string"
},
"src": {
"description": "The script source",
"type": "string"
},
"type": {
"description": "The script MIME type",
"type": "string"
}
},
"required": [
"src",
"async",
"referrerpolicy",
"crossorigin",
"integrity",
"type",
"id",
"nonce",
"node_type"
],
"title": "ScriptAttributes represent script nodes which load javascript.",
"type": "object"
},
"uiNodeInputAttributes": {
"description": "InputAttributes represents the attributes of an input node",
"properties": {
"type": {
"description": "The input's element type.",
"enum": [
"text",
"password",
"number",
"checkbox",
"hidden",
"email",
"tel",
"submit",
"button",
"datetime-local",
"date",
"url"
],
"type": "string"
},
"typeenum": {
"description": "The input's element type.",
"enum": [
"text",
"password",
"number",
"checkbox",
"hidden",
"email",
"tel",
"submit",
"button",
"datetime-local",
"date",
"url"
],
"type": "string"
}
},
"required": [
"type",
"typeenum"
],
"type": "object"
},
In the example above, the file ui_node_attributes.rs
contains a large enum definition for the discriminator but is missing TypeEnum
:
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "nodetype")]
pub enum UiNodeAttributes {
#[serde(rename="a")]
UiNodeAnchorAttributes {
// ...
},
#[serde(rename="img")]
UiNodeImageAttributes {
// ...
},
#[serde(rename="input")]
UiNodeInputAttributes {
// ...
/// The input's element type.
#[serde(rename = "type")]
// true, false, TypeEnum, String, false
_type: TypeEnum,
/// The input's element type.
#[serde(rename = "typeenum")]
// true, false, TypeenumEnum, String, false
typeenum: TypeenumEnum,
// ..
},
// ..
}
/// The autocomplete attribute for the input.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum AutocompleteEnum {
#[serde(rename = "email")]
Email,
#[serde(rename = "tel")]
Tel,
#[serde(rename = "url")]
Url,
#[serde(rename = "current-password")]
CurrentPassword,
#[serde(rename = "new-password")]
NewPassword,
#[serde(rename = "one-time-code")]
OneTimeCode,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum TypeenumEnum {
#[serde(rename = "text")]
Text,
#[serde(rename = "password")]
Password,
#[serde(rename = "number")]
Number,
#[serde(rename = "checkbox")]
Checkbox,
#[serde(rename = "hidden")]
Hidden,
#[serde(rename = "email")]
Email,
#[serde(rename = "tel")]
Tel,
#[serde(rename = "submit")]
Submit,
#[serde(rename = "button")]
Button,
#[serde(rename = "datetime-local")]
DatetimeLocal,
#[serde(rename = "date")]
Date,
#[serde(rename = "url")]
Url,
}
As you can see above, the two enums TypeenumEnum
and AutocompleteEnum
are correctly marked as "enums" and included, TypeEnum
however is missing. This happens because the uiNodeScriptAttributes
also has a key called type
:
"type": {
"description": "The script MIME type",
"type": "string"
}
which is clashing with the type
field from uiNodeInputAttributes
:
"type": {
"description": "The input's element type.",
"enum": [
"text",
"password",
"number",
"checkbox",
"hidden",
"email",
"tel",
"submit",
"button",
"datetime-local",
"date",
"url"
],
"type": "string"
},
I was able to identify this by adding the following debug statement to model.mustache
of the Rust generator:
{{!-- for properties that are of enum type --}}
{{#vars}}
+/*
+{{{.}}}
+*/
{{#isEnum}}
/// {{{description}}}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum {{{enumName}}} {
{{#allowableValues}}
{{#enumVars}}
#[serde(rename = "{{{value}}}")]
{{{name}}},
{{/enumVars}}
{{/allowableValues}}
}
{{/isEnum}}
{{/vars}}
which then showed that there is only one variable called type
and it is coming from the script definition:
If I change the order and move #/components/schemas/uiNodeInputAttributes
below #/components/schemas/uiNodeScriptAttributes
, the enum TypeEnum
is correctly generated. However, this is only a temporary solution as it would still clashes with the other property definition.
openapi-generator version
All versions of 5.x and 6.x are affected
OpenAPI declaration file content or url
https://gist.github.com/aeneasr/c201992378c87943dfdbe559adc32bae
Generation Details
rust.yml
packageName: ory-client
packageVersion: v0.2.0-alpha.13
library: reqwest
supportAsync: true
enumNameSuffix: Enum
Steps to reproduce
Use spec file https://gist.github.com/aeneasr/c201992378c87943dfdbe559adc32bae
openapi-generator-cli version-manager set 6.0.1
openapi-generator-cli generate -i "${SPEC_FILE}" \
-g rust \
-o "$dir" \
--git-user-id ory \
--git-repo-id sdk \
--git-host github.com \
-c ./config/client/rust.yml
Related issues/PRs
None
Suggest a fix
Looks like this has to be fixed outside of the templates and in the Java code base?