Skip to content

Latest yams results in incomplete generation of types #565

@dpasirst

Description

@dpasirst

Description

I'm not exactly sure where this bug is arising from (e.g. swift-openapi-generator or one of its dependencies like OpenAPIKit).

In short, using swift-openapi-generator with when the yams version is 5.0.X, the correct swift code (Types) is generated as part of generating types and client. When yams is 5.1.X, the generated code is missing fields. This is with an OpenAPI 3.1 json.

Reproduction

I have attached an example openapi.json along with the difference in the resulting generated swift code. Specifically, in looking at Components.Schemas.NewAccount and Components.Schemas.Account you will see that the one created with yams 5.0.X contains a phoneNumberPayload as part of each. There is also a defined PhoneNumber struct and curiously it is not linked or used instead of phoneNumberPayload but that is perhaps a different improvement. For now, the phoneNumberPayload is usable with yams 5.0.X.

However, when building with yams 5.1.X, the generated NewAccount and Account do not contain phoneNumberPayload. It is dropped but should be there.

I have attached the example openapi.json and the example generated outputs.

openapi.json
generated_types_yams5.0.swift.txt
generated_types_yams5.1.swift.txt

I'm not sure if this is related but Yams 5.1.0 release notes the following breaking change:

Change how empty strings are decoded into nullable properties.
key: "" previously decoded into
struct Value: Codable { let key: String? } as Value(key: nil)
whereas after this change it decodes as Value(key: "").
This could be a breaking change if you were relying on the previous
semantics.

If it is helpful, the openapi.json was generated via Rust using Aide with Axum.

Rust struct definition
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
pub enum Role {
    #[default]
    #[serde(rename="user")]
    User,
    #[serde(rename="admin")]
    Admin,
}

#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
pub struct PhoneNumber {
    /// country code must contain only a set of digits 0-9
    /// it should be formatted without leading zeros.
    /// for example: U.S.A. should be `1` without `+` and without `00` e.g. not `001`
    /// it should be assumed that the `+` would be added by the system
    #[serde(rename = "countryCode")]
    pub country_code: String,

    /// the number should be a set of digits "333555222"
    /// without parens or dashes. It should not contain the country code
    /// however it should be formatted such that combining a `+` countryCode number
    /// would result in a complete functional international phone number
    #[serde(rename = "number")]
    pub number: String
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
pub struct NewAccount {

    /// username as A-Za-z0-9
    #[serde(rename = "username")]
    pub username: String,

    /// email address
    #[serde(rename = "email")]
    pub email: Option<String>,

    /// phone number
    #[serde(rename = "phoneNumber")]
    pub phone_number: Option<PhoneNumber>,

    /// The code (string) for referrals
    #[serde(rename = "role")]
    pub role: Role,

}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
pub struct Account {

    /// internal uuid for the user
    #[serde(rename = "id")]
    pub id: Uuid,

    /// username as A-Za-z0-9
    #[serde(rename = "username")]
    pub username: String,

    /// email address
    #[serde(rename = "email")]
    pub email: Option<String>,

    /// phone number
    #[serde(rename = "phoneNumber")]
    pub phone_number: Option<PhoneNumber>,

    /// The code (string) for referrals
    #[serde(rename = "role")]
    pub role: Role,

}

Package version(s)

OpenAPIKit 3.1.3
swift-algorithms 1.2.0
swift-argument-parser 1.3.1
swift-collections 1.1.0
swift-http-types 1.0.3
swift-numerics 1.0.2
swift-openapi-generator 1.2.1
swift-openapi-runtime 1.4.0
swift-openapi-urlsession 1.0.1
Yams 5.0.6 or 5.1.0 as described resulting in the problem

Expected behavior

The generated types for Account and NewAccount should contain phoneNumberPayload respectively (or even better if it directly contained PhoneNumber) for any version of Yams.

Environment

$ swift -version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: x86_64-apple-macosx14.0

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/enhancementImprovements to existing feature.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions