yonaskolb / SwagGen

OpenAPI/Swagger 3.0 Parser and Swift code generator
MIT License
627 stars 148 forks source link

modelType:struct creates structs with inheritance #276

Open Holek opened 3 years ago

Holek commented 3 years ago

First, I want to preface that I am not a Swift developer, but I've noticed an odd behaviour in model template generation.

Using --option "modelType:struct" the generator creates models as structs, but allows them to inherit from each other. As far as I understand, a struct cannot inherit from another kind of struct.

Example

Here's an example struct-issue.yaml that recreates this:

openapi: 3.0.0
info:
  title: Sample Struct Service
  description: 'Model definitions for struct inheritance issue'
  version: 0.0.1
components:
  schemas:
    User:
      description: a member profile
      type: object
      properties:
        user-id:
          description: The member's unique ID
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-email
        name:
          description: The member's name
          type: string
          example: 'Jane Doe'
    AdminUser:
      description: A user profile including information only returned by admin endpoints
      allOf:
        - $ref: '#/components/schemas/User'
        - type: object
          properties:
            latestLoggedInAt:
              description: Last login from the user
              type: string
              format: datetime

I've recreated this problem by running:

$ swaggen generate --option "modelType:struct" --destination struct-issue struct-issue.yaml

In the generated files you can see struct-issue/Sources/Models/AdminUser.swift

import Foundation

/** A user profile including information only returned by admin endpoints */
public struct AdminUser: User {

    /** Last login from the user */
    public var latestLoggedInAt: String?

    public init(name: String? = nil, userId: ID? = nil, latestLoggedInAt: String? = nil) {
        self.latestLoggedInAt = latestLoggedInAt
        super.init(name: name, userId: userId)
    }

which looks like a compilation error to me.

Possible workarounds for now

This is a list of possible workarounds for people who might also encounter this issue.

  1. Don't use $refs in openapi to generate structs
  2. Use classes (default behaviour of Swaggen)

Possible fix

A possible fix would be to read any references in models that occur and hard-code schemas that are inherited in structs. I don't know how hard would such fix look like, but I believe you would have some ideas for that.

Thanks otherwise for a very helpful tool!

yonaskolb commented 3 years ago

Hi @Holek. You should be able to use --option modelInheritance:false

Holek commented 3 years ago

Interesting, that will work, indeed! So now the question I would have is whether modelType:struct should imply modelInheritance:false?

yonaskolb commented 3 years ago

Yes it probably should, but currently they are unlinked