You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
The structure generated by models using oneOf cannot be easily or efficiently converted to the specific structure type.
Using the provided declaration, with the current implementation of oneOf and anyOf handling, generates a Message struct with a private field of the RawValue type, with 2 additional structures named Hello and Goodbye that have usable fields and traits. The generated endpoint Default/foo gets Message provided as one of its arguments, but this type is mostly useless. There is no enumeration or information available within the structure to facilitate obtaining the adequate model programmatically, with no guarantee that further modifications to the model (ones that add or remove fields to the list of variants) will have explicit handling within the user code. The only way to currently use the Message structure semi-reasonably is done by attempting to deserialize Hello and Goodbye from Message and seeing which one does not fail, or deserializing Value from Message, manually checking the tagged field, and generating the adequate type from there. Both of these options complicate the error handling and the use of the values, as they have separate types and cannot be assigned to the same variable.
Internally tagged enums are used when discriminator.propertyName is defined:
#[derive(Serialize,Deserialize)]#[serde(tag = "op")]pubenumMessage{// ` mapping`s would lead to aliases#[serde(alias = "Hello", alias = "Greetings")]Hello(Hello),#[serde(alias = "Goodbye")]Goodbye(Goodbye),}// Note that tagged enums do not deserialize the tag to a field. If it were to be necessary, a possible// solution to this would be to generate a method with the tag field name that returns the value.// eg. `fn op() -> &'static str { "Hello" }`#[derive(Serialize,Deserialize)]pubstructHello{pubwelcome_message:String,}#[derive(Serialize,Deserialize)]pubstructGoodbye{pubgoodbye_message:String,}
This solution could also be reused to support inline enums in the future, and oneOf enum mappings from OpenAPI 3.1 (see this stack overflow)
The text was updated successfully, but these errors were encountered:
The rust generator does create useful models, very similar to my suggested solution. It however does not do content validation and type matching (integers are always i32), so getting it ported will not be simple, but should be doable.
I've been attempting to implement the updated model with adequate oneOf support and noticed that the models generated by the rust client are wrong. Hello and Goodbye in the example declaration generate with the op field, but this makes the structure unuseable, as serde doesn't serialize the field specified in the tag on the structures, and will always lead to a missing field "op", line: 0, column: 0 error.
Bug Report Checklist
Description
The structure generated by models using
oneOf
cannot be easily or efficiently converted to the specific structure type.Using the provided declaration, with the current implementation of
oneOf
andanyOf
handling, generates aMessage
struct with a private field of theRawValue
type, with 2 additional structures namedHello
andGoodbye
that have usable fields and traits. The generated endpointDefault/foo
getsMessage
provided as one of its arguments, but this type is mostly useless. There is no enumeration or information available within the structure to facilitate obtaining the adequate model programmatically, with no guarantee that further modifications to the model (ones that add or remove fields to the list of variants) will have explicit handling within the user code. The only way to currently use theMessage
structure semi-reasonably is done by attempting to deserializeHello
andGoodbye
fromMessage
and seeing which one does not fail, or deserializingValue
fromMessage
, manually checking the tagged field, and generating the adequate type from there. Both of these options complicate the error handling and the use of the values, as they have separate types and cannot be assigned to the same variable.openapi-generator version
7.10.0-SNAPSHOT
OpenAPI declaration file content or url
https://gist.github.com/Victoria-Casasampere-BeeTheData/e6c856d1dad01e64e21fa0f7701759d4
Generation Details
openapi-generator-cli generate -g rust-axum -o outoutrs -i base.yaml
Steps to reproduce
Use the
rust-axum
generator with the provided declaration or any declaration usingoneOf
as a model content.Related issues/PRs
Possibly #15, but most likely none.
Suggest a fix
I would replace the current implementation with one that uses
enum
serde representations instead.Untagged would be used when
discriminator
is not defined:Internally tagged enums are used when
discriminator.propertyName
is defined:This solution could also be reused to support inline enums in the future, and
oneOf
enum mappings from OpenAPI 3.1 (see this stack overflow)The text was updated successfully, but these errors were encountered: