Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rust): oneOf generation for client #17915

Merged
merged 14 commits into from Feb 24, 2024

Conversation

DDtKey
Copy link
Contributor

@DDtKey DDtKey commented Feb 21, 2024

Closes #17869, #17896, #9497 and also includes unmerged #17898 (fix of serde::rename mappings)

Unfortunately it affects quite a lot of code, but we can see that only client-side models were affected by re-generation.
I tried to split this PR to several, but they're really coupled and hard to create a chain of PRs (e.g #14898 & #17899 and issue with imports).

Other changes:

  • imports are aligned between Rust codegens viaAbstractRustCodegen (it used to be error-prone copy/paste with small differences for server & client)
  • related improvement is described here: fix(rust): oneOf generation for client #17915 (comment)
  • fixed number representation: f32 -> f64

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/configs/*.yaml
    ./bin/utils/export_docs_generators.sh
    
    (For Windows users, please run the script in Git BASH)
    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*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.1.0 minor release - breaking changes with fallbacks), 8.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

Discriminator mapping has been ignored in some cases.
Even existing samples had wrong definition in some cases

This PR addresses this
Solves OpenAPITools#17869 and OpenAPITools#17896 and also includes unmerged $17898

Unfortunately it affects quite a lot of code, but we can see that only client-side models were affected by re-generation.
I tried to split this PR to several, but they're really coupled and hard to create a chain of PRs.
@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 21, 2024

modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml covers issue described in #17869 pretty well

But JFYI, it generates the following enum against example in that PR:

/// Either an account name or an email.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AccountOrEmail {
    /// An email address.
    Email(Box<String>),
    /// An account name.
    AccountName(Box<String>),
}

cc @RobbieMcKinstry

Copy link
Contributor

@ctrlaltf24 ctrlaltf24 left a comment

Choose a reason for hiding this comment

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

Thanks for the fixes @DDtKey ! Doesn't look like the samples compile as-is.

cd rust/client/others/rust
cargo check

nor does the cli compile

docker build .

Will look at it in-depth tomorrow to help this along, though we'll still need approval from rust maintainers

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 21, 2024

There were missing changes, sorry

cargo check works on the latest commit

UPD: however I see issues for petstore. Will fix a bit later. I see the reason
UPD 2: fixed

@DDtKey DDtKey force-pushed the fix-imports-rust-enums branch 2 times, most recently from 70976e5 to 671003b Compare February 21, 2024 12:20
@@ -8,6 +8,7 @@
* Generated by: https://openapi-generator.tech
*/

use crate::models;
Copy link
Contributor Author

@DDtKey DDtKey Feb 21, 2024

Choose a reason for hiding this comment

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

A lot of client files contain only such changes - it's now aligned with server-side generators (via AbstractRustCodegen).
Also indentation is fixed in models (used to be too many extra blank lines)

Comment on lines +236 to +237
@Override
public String getTypeDeclaration(Schema p) {
Copy link
Contributor Author

@DDtKey DDtKey Feb 21, 2024

Choose a reason for hiding this comment

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

It was error-prone because almost copy-paste between rust-generators, so only extracted to AbstractRustCodegen and unified with client .

We can see that only client samples were affected by this PR.

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 21, 2024

PR is ready for review, cleaned-up the code a bit

@RobbieMcKinstry
Copy link

modules/openapi-generator/src/test/resources/3_0/oneOfArrayMapImport.yaml covers issue described in #17869 pretty well

But JFYI, it generates the following enum against example in that PR:

/// Either an account name or an email.
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AccountOrEmail {
    /// An email address.
    Email(Box<String>),
    /// An account name.
    AccountName(Box<String>),
}

cc @RobbieMcKinstry

That looks good to me! It's not obvious to me why the Strings have to be boxed, but that's not even a minor concern for me. 👍🏻

Thank you very much for this PR! ❤️

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 21, 2024

It's not obvious to me why the Strings have to be boxed

Yeah, also find this confusing.
But I don't want to change too much in this PR. I think it can be separate PR to clean-up Box usage. Because this behavior existed before.

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 21, 2024

Just pushed one more improvement:

  • prefer mapping name for enum variant if present
  • handle the case when mapping has the same ref with different names. E.g:
      "Fruit": {
        "type": "object",
        "oneOf": [
          {
            "$ref": "#/components/schemas/Apple"
          },
          {
            "$ref": "#/components/schemas/Apple"
          }
        ],
        "discriminator": {
          "propertyName": "kind",
          "mapping": {
            "red_apple": "#/components/schemas/Apple",
            "green_apple": "#/components/schemas/Apple"
          }
        }
      },

The result is the following:

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind")]
pub enum Fruit {
  RedApple(Box<models::Apple>),
  GreenApple(Box<models::Apple>),
}

UPD: added test coverage for this

Copy link
Contributor

@ctrlaltf24 ctrlaltf24 left a comment

Choose a reason for hiding this comment

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

concerns addressed, LGTM. Works with my openapi definition that motivated the original change.

Thanks @DDtKey !

@wing328
Copy link
Member

wing328 commented Feb 22, 2024

thanks for the PR. please review the build failure when you've time, e.g. https://github.com/OpenAPITools/openapi-generator/actions/runs/7996641152/job/21865620537?pr=17915

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 22, 2024

Ouch, sorry, my bad - there is no such method for the interface, but only for a particular type.

Fixed, build works as expected (at least locally)

@DDtKey
Copy link
Contributor Author

DDtKey commented Feb 23, 2024

Sorry, @wing328 any chance it will be merged soon?

CI is green and I'd like to update #17931 once this one is merged 🙂

@wing328
Copy link
Member

wing328 commented Feb 24, 2024

lgtm. let's give it a try

have a nice weekend

@wing328 wing328 merged commit 518b29d into OpenAPITools:master Feb 24, 2024
18 checks passed
oscarr-reyes pushed a commit to oscarr-reyes/openapi-generator that referenced this pull request Feb 25, 2024
* fix(rust): discriminator mapping to serde rename

Discriminator mapping has been ignored in some cases.
Even existing samples had wrong definition in some cases

This PR addresses this

* fix(rust): `oneOf` generation for client

Solves OpenAPITools#17869 and OpenAPITools#17896 and also includes unmerged $17898

Unfortunately it affects quite a lot of code, but we can see that only client-side models were affected by re-generation.
I tried to split this PR to several, but they're really coupled and hard to create a chain of PRs.

* fix: indentation in `impl Default`

* missing fixes

* fix: correct typeDeclaration with unaliased schema

* style: improve indentation for models

* fix: user toModelName for aliases of oneOf

* refactor: unify `getTypeDeclaration` for rust

* cover the case when `mapping` has the same `ref` for different mapping names

* test: add test for previous change

* style: remove extra qualified path to models

* add some comments

* fix(build): use method of `List` instead of specific for `LinkedList`
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.

[BUG] [RUST] Enum Varients Merging Incorrectly, breaking change
4 participants