Skip to content

Conversation

@ctrlaltf24
Copy link
Contributor

@ctrlaltf24 ctrlaltf24 commented Nov 9, 2022

Generates oneOf enums.

openapi: 3.0.1

info:
  version: "1.0.0"
  title: rust one-of fix
paths: {}
components:
  schemas:
    Foo:
      x-one-of-name: Foo
      oneOf:
        - type: object
          required:
            - field_one
          properties:
            field_one:
              type: string
            field_two:
              type: string
        - type: object
          required:
            - field_three
          properties:
            field_three:
              type: number

Expected behavior: Able to fill in struct fields in such a way that creates a valid request
Actual behavior (on master): Impossible to fill the struct Foo to make it a valid schema (as BOTH required fields (field_one and field_three) are required to be filled in rust, yet the openapi schema only allows one or the other to be set.
Actual behavior (on this PR): able to fill fields by using the corresponding variant on the enum Foo.

use super::FooOneOf;
use super::FooOneOf1;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum Foo {
    FooOneOf(Box<FooOneOf>),
    FooOneOf1(Box<FooOneOf1>),
}

Known Limitations

  • model.mds still need to be updated to match the new enum scheme

Related issue

#9497

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package 
    ./bin/generate-samples.sh
    ./bin/utils/export_docs_generators.sh
    
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master (6.3.0) (minor release - breaking changes with fallbacks), 7.0.x (breaking changes without fallbacks)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@frol @farcaller @richardwhiuk @paladinzh @jacob-pro

@wing328
Copy link
Member

wing328 commented Nov 10, 2022

@nshaaban-cPacket thanks for the PR. Can you please PM me via Slack when you've time?

https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g

@ctrlaltf24
Copy link
Contributor Author

ctrlaltf24 commented Nov 11, 2022

kk after talking to @wing328 :

@wing328
Copy link
Member

wing328 commented Dec 27, 2022

@nshaaban-cPacket is this PR ready for another review?

cc @frol @farcaller @richardwhiuk @paladinzh @jacob-pro

@ctrlaltf24
Copy link
Contributor Author

ctrlaltf24 commented Dec 27, 2022

@nshaaban-cPacket is this PR ready for another review?

yup! May need to re-run CI, error appears unrelated to code changes

@wing328
Copy link
Member

wing328 commented Dec 27, 2022

right, the circleci node1 failure can be ignore.

@mattoni
Copy link

mattoni commented Jan 5, 2023

Is there anything still blocking this being merged? Excited to have this in :)

@ctrlaltf24
Copy link
Contributor Author

Is there anything still blocking this being merged? Excited to have this in :)

Just waiting on review from some of the rust technical community. Feel free to give a try yourself in the meantime!

@wing328 wing328 modified the milestones: 6.3.0, 6.3.1 Jan 20, 2023
@wing328
Copy link
Member

wing328 commented Feb 8, 2023

@nshaaban-cPacket thanks for the PR. Is it correct to say that the oneOf implementation uses Rust's enum?

@ctrlaltf24
Copy link
Contributor Author

@nshaaban-cPacket thanks for the PR. Is it correct to say that the oneOf implementation uses Rust's enum?

Correct, this PR uses an enum for oneOf. Current version doesn't use a struct (similar to a class in other languages) with optional fields

@wing328
Copy link
Member

wing328 commented Feb 17, 2023

@nshaaban-cPacket can it handle the following?

    RgbColor:
      description: RGB three element array with values 0-255.
      type: array
      items:
        type: integer
        minimum: 0
        maximum: 255
      minItems: 3
      maxItems: 3
    RgbaColor:
      description: RGBA four element array with values 0-255.
      type: array
      items:
        type: integer
        minimum: 0
        maximum: 255
      minItems: 4
      maxItems: 4
    HexColor:
      description: 'Hex color string, such as #00FF00.'
      type: string
      pattern: ^#(?:[0-9a-fA-F]{3}){1,2}$
      minLength: 7
      maxLength: 7
    Color:
      description: RGB array, RGBA array, or hex string.
      oneOf:
      - $ref: '#/components/schemas/RgbColor'
      - $ref: '#/components/schemas/RgbaColor'
      - $ref: '#/components/schemas/HexColor'


@wing328 wing328 modified the milestones: 6.4.0, 6.5.0 Feb 19, 2023
temp.yaml Outdated
@@ -0,0 +1,34 @@
openapi: 3.0.1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to commit this file?

@wing328 wing328 modified the milestones: 6.5.0, 6.6.0 Apr 1, 2023
@wing328 wing328 modified the milestones: 6.6.0, 7.0.0 May 11, 2023
@ctrlaltf24
Copy link
Contributor Author

ctrlaltf24 commented May 31, 2023

@nshaaban-cPacket can it handle the following?

TL;DR; no due to an existing limitation on master, however this PR does do it's part in switching the type of Color to an enum.

Given a config of

generatorName: rust
outputDir: samples/client/others/rust/hyper/oneOf-color
library: hyper
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust/color.yaml
templateDir: modules/openapi-generator/src/main/resources/rust
generateAliasAsModel: true
additionalProperties:
  supportAsync: "false"
  packageName: oneof-color-hyper

And a openapi of

openapi: 3.0.0
servers:
  - url: 'http://localhost'
info:
  description: >-
    This is a simple sample for oneOf support
  version: 1.0.0
  title: OpenAPI Color
  license:
    name: Apache-2.0
    url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
paths:
  /color:
    get:
      summary: Get the current color
      description: ''
      operationId: getColor
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Color'
components:
  schemas:
    RgbColor:
      description: RGB three element array with values 0-255.
      type: array
      items:
        type: integer
        minimum: 0
        maximum: 255
      minItems: 3
      maxItems: 3
    RgbaColor:
      description: RGBA four element array with values 0-255.
      type: array
      items:
        type: integer
        minimum: 0
        maximum: 255
      minItems: 4
      maxItems: 4
    HexColor:
      description: 'Hex color string, such as #00FF00.'
      type: string
      pattern: ^#(?:[0-9a-fA-F]{3}){1,2}$
      minLength: 7
      maxLength: 7
    Color:
      description: RGB array, RGBA array, or hex string.
      oneOf:
      - $ref: '#/components/schemas/RgbColor'
      - $ref: '#/components/schemas/RgbaColor'
      - $ref: '#/components/schemas/HexColor'

It correctly generates the Color model as the following

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Color {
    /// RGB array, RGBA array, or hex string.
    RgbColor(Box<RgbColor>),
    /// RGB array, RGBA array, or hex string.
    RgbaColor(Box<RgbaColor>),
    /// RGB array, RGBA array, or hex string.
    String(Box<String>),
}

However the current state of the rust generator (as it exists both on master and this PR) fails to generate the correct model for the aliases. This issue exists on master as well, and is out of scope of the PR to fix. A separate PR could be created to fix this, and in combination with this PR would result in complete support for the given spec.

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct RgbColor {
}

@wing328
Copy link
Member

wing328 commented Aug 11, 2023

@ctrlaltf24 can you please resolve the merge conflicts when you've time?

there's been change to the rust client generator so not sure if it has addressed the existing limitations you mentioned above.

@wing328 wing328 removed this from the 7.0.0 milestone Aug 11, 2023
@humb1t
Copy link
Contributor

humb1t commented Dec 14, 2023

@ctrlaltf24 I made a PR with rebased master to your fork, hope it can help ctrlaltf24#1

@ctrlaltf24 ctrlaltf24 force-pushed the basic-rust-anyof-support branch from c9fecdd to d0af4ad Compare December 14, 2023 22:23
@ctrlaltf24 ctrlaltf24 force-pushed the basic-rust-anyof-support branch from d0af4ad to c9fecdd Compare December 14, 2023 22:29
@humb1t
Copy link
Contributor

humb1t commented Dec 15, 2023

@wing328 - @ctrlaltf24 merged rebase onto master branch in his fork

@ctrlaltf24 ctrlaltf24 force-pushed the basic-rust-anyof-support branch from c9fecdd to 6a90a83 Compare February 7, 2024 20:05
@ctrlaltf24 ctrlaltf24 marked this pull request as draft February 7, 2024 20:09
Suport oneOf as a rust struct enum.

Details:

Enum without a discriminator is untagged being
"untagged" simply means serde won't attempt to
store the name of the enum inside the serialized
object. See
https://serde.rs/enum-representations.html#untagged
for more

Also check to make sure the mapping values
are not an empty object (aka null).

Co-authored-by: Nikita Puzankov <[email protected]>
@ctrlaltf24 ctrlaltf24 force-pushed the basic-rust-anyof-support branch from 6a90a83 to f65ed95 Compare February 7, 2024 20:31
No longer needed as of reqwest 0.10, it now takes the response as owned instead of mut ref.

Is not empty is more clear
Will show as a struct enum when there are additional fields, otherwise will be a tuple enum.

not sure the purpose of x-mapped-models, perhaps legacy code? mappedModels appears to do the same thing.

Also add default implementation for quality of life
@ctrlaltf24 ctrlaltf24 marked this pull request as ready for review February 7, 2024 23:42
@yaar-trail
Copy link

This will be super helpful! Thanks. @wing328

@wing328
Copy link
Member

wing328 commented Feb 13, 2024

I also did a test to manually trigger a build failure and the workflow caught the issue as expected: https://github.com/OpenAPITools/openapi-generator/actions/runs/7885693679/job/21517363148?pr=17854

let's give this PR a try.

thanks again for the contribution.

@wing328 wing328 merged commit c30d369 into OpenAPITools:master Feb 13, 2024
@ctrlaltf24 ctrlaltf24 deleted the basic-rust-anyof-support branch February 13, 2024 21:54
kota65535 pushed a commit to kota65535/openapi-generator that referenced this pull request Feb 23, 2024
* [rust] basic oneOf support

Suport oneOf as a rust struct enum.

Details:

Enum without a discriminator is untagged being
"untagged" simply means serde won't attempt to
store the name of the enum inside the serialized
object. See
https://serde.rs/enum-representations.html#untagged
for more

Also check to make sure the mapping values
are not an empty object (aka null).

Co-authored-by: Nikita Puzankov <[email protected]>

* refactor: fix clippy lints

No longer needed as of reqwest 0.10, it now takes the response as owned instead of mut ref.

Is not empty is more clear

* fix: discriminator and oneof case

Will show as a struct enum when there are additional fields, otherwise will be a tuple enum.

not sure the purpose of x-mapped-models, perhaps legacy code? mappedModels appears to do the same thing.

Also add default implementation for quality of life

* chore: update samples

---------

Co-authored-by: Nikita Puzankov <[email protected]>
@wing328 wing328 added this to the 7.4.0 milestone Mar 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants