Bug Report Checklist
Description
oneOf support for models is broken for rust-client. Serde will always fail when parsing responses that contain a model with oneOf
openapi-generator version
5.1.1 and also tested with master
OpenAPI declaration file content or url
https://raw.githubusercontent.com/ory/sdk/master/spec/kratos/v0.6.2-alpha.1.json
There are two problematic cases of oneOf in that spec
The first one is a case in which all possible values are json scalar values. For example:
"uiNodeInputAttributesValue": {
"oneOf": [
{ "type": "string" },
{ "type": "number" },
{ "type": "boolean" }
]
},
gets trasnformed into
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct UiNodeInputAttributesValue {
}
impl UiNodeInputAttributesValue {
pub fn new() -> UiNodeInputAttributesValue {
UiNodeInputAttributesValue {
}
}
}
but this is wrong because UiNodeInputAttributesValue is not a struct.
My hack for this particular case is to use:
pub type UiNodeInputAttributesValue = serde_json::Value;
However, this does not solve all cases, since oneOf can also be used with references to other schemas. Indeed, there is another problematic case in this spec:
"uiNodeAttributes": {
"oneOf": [
{ "$ref": "#/components/schemas/uiNodeInputAttributes" },
{ "$ref": "#/components/schemas/uiNodeTextAttributes" },
{ "$ref": "#/components/schemas/uiNodeImageAttributes" },
{ "$ref": "#/components/schemas/uiNodeAnchorAttributes" }
],
"title": "Attributes represents a list of attributes (e.g. `href=\"foo\"` for links)."
},
Since this is a valid spec and all the models are present, the files for each type of uiNodeAttributes is created ok and accurately. However, the generated code for uiNodeAttributes is incorrect. The output result merges all properties like:
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct UiNodeAttributes {
/// Sets the input's disabled field to true or false.
#[serde(rename = "disabled")]
pub disabled: bool,
#[serde(rename = "label", skip_serializing_if = "Option::is_none")]
pub label: Option<Box<crate::models::UiText>>,
/// The input's element name.
#[serde(rename = "name")]
pub name: String,
/// The input's pattern.
#[serde(rename = "pattern", skip_serializing_if = "Option::is_none")]
pub pattern: Option<String>,
/// Mark this input field as required.
#[serde(rename = "required", skip_serializing_if = "Option::is_none")]
pub required: Option<bool>,
#[serde(rename = "type")]
pub _type: String,
#[serde(rename = "value", skip_serializing_if = "Option::is_none")]
pub value: Option<Box<crate::models::UiNodeInputAttributesValue>>,
#[serde(rename = "text")]
pub text: Box<crate::models::UiText>,
/// The image's source URL. format: uri
#[serde(rename = "src")]
pub src: String,
/// The link's href (destination) URL. format: uri
#[serde(rename = "href")]
pub href: String,
#[serde(rename = "title")]
pub title: Box<crate::models::UiText>,
}
impl UiNodeAttributes {
pub fn new(disabled: bool, name: String, _type: String, text: crate::models::UiText, src: String, href: String, title: crate::models::UiText) -> UiNodeAttributes {
UiNodeAttributes {
disabled,
label: None,
name,
pattern: None,
required: None,
_type,
value: None,
text: Box::new(text),
src,
href,
title: Box::new(title),
}
}
}
But this is extremely problematic and wrong, as that struct will never exist. UiNodeAttributes is assumed to have ALL properties from the polymorphic types. Since each of those types have different required properties, the UiNodeAttributes assumes that ALL required properties will always exist, which will never happen.
Generation Details
docker run --rm -v "${PWD}:/local" \
--user 1001:1001 \
openapitools/openapi-generator-cli generate \
-i https://raw.githubusercontent.com/ory/sdk/master/spec/kratos/v0.6.2-alpha.1.json \
-c /local/options.yaml \
-g rust \
-o /local/packages/kratos
Steps to reproduce
Run the command above
Related issues/PRs
#2244 added support for multiple response types, but not for oneOf
Suggest a fix
Ideally, the generated code should generate Rust enums in the same way that polymorphism is treated with response errors
Another solution could be to continue merging all possible properties but make them all Option
The accepted answer in https://stackoverflow.com/questions/37561593/how-can-i-use-serde-with-a-json-array-with-different-objects-for-successes-and-e summarises the two possibilities
Bug Report Checklist
Description
oneOfsupport for models is broken for rust-client. Serde will always fail when parsing responses that contain a model withoneOfopenapi-generator version
5.1.1 and also tested with master
OpenAPI declaration file content or url
https://raw.githubusercontent.com/ory/sdk/master/spec/kratos/v0.6.2-alpha.1.json
There are two problematic cases of
oneOfin that specThe first one is a case in which all possible values are json scalar values. For example:
gets trasnformed into
but this is wrong because
UiNodeInputAttributesValueis not a struct.My hack for this particular case is to use:
However, this does not solve all cases, since
oneOfcan also be used with references to other schemas. Indeed, there is another problematic case in this spec:Since this is a valid spec and all the models are present, the files for each type of
uiNodeAttributesis created ok and accurately. However, the generated code foruiNodeAttributesis incorrect. The output result merges all properties like:But this is extremely problematic and wrong, as that struct will never exist.
UiNodeAttributesis assumed to have ALL properties from the polymorphic types. Since each of those types have different required properties, theUiNodeAttributesassumes that ALL required properties will always exist, which will never happen.Generation Details
Steps to reproduce
Run the command above
Related issues/PRs
#2244 added support for multiple response types, but not for
oneOfSuggest a fix
Ideally, the generated code should generate Rust
enumsin the same way that polymorphism is treated with response errorsAnother solution could be to continue merging all possible properties but make them all
OptionThe accepted answer in https://stackoverflow.com/questions/37561593/how-can-i-use-serde-with-a-json-array-with-different-objects-for-successes-and-e summarises the two possibilities