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

[gen] Concrete subtypes of a sum type referenced directly without nesting or proper import #2868

Closed
hochgi opened this issue May 26, 2024 · 0 comments · Fixed by #2869
Closed
Labels
bug Something isn't working

Comments

@hochgi
Copy link
Contributor

hochgi commented May 26, 2024

Describe the bug
When we have a sealed trait and subtypes reside inside trait's companion,
we also need to make sure that any other object referencing concrete subtype directly, will nest under companion.

To Reproduce
Try to generate from the following yaml:

info:
  title: Animals Service
  version: 0.0.1
servers:
  - url: http://127.0.0.1:5000/
tags:
  - name: Animals_API
paths:
  /api/v1/zoo/{animal}:
    get:
      operationId: get_animal
      parameters:
        - in: path
          name: animal
          schema:
            type: string
          required: true
      tags:
        - Animals_API
      description: Get animals by species name
      responses:
        "200":
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Animal'
          description: OK
openapi: 3.0.3
components:
  schemas:
    Animal:
      oneOf:
        - $ref: '#/components/schemas/Alligator'
        - $ref: '#/components/schemas/Zebra'
    AnimalSharedFields:
      type: object
      required:
        - age
        - weight
      properties:
        age:
          type: integer
          format: int32
          minimum: 0
        weight:
          type: number
          format: float
          minimum: 0
    Alligator:
      allOf:
        - $ref: '#/components/schemas/AnimalSharedFields'
        - type: object
          required:
            - num_teeth
          properties:
            num_teeth:
              type: integer
              format: int32
              minimum: 0
    Zebra:
      allOf:
        - $ref: '#/components/schemas/AnimalSharedFields'
        - type: object
          required:
            - num_stripes
          properties:
            num_stripes:
              type: integer
              format: int32
              minimum: 0
    Lion:
      type: object
      required:
        - eats
      properties:
        eats:
          $ref: '#/components/schemas/Zebra'

And you'll see the code does not compile:
Screenshot 2024-05-26 at 23 41 11

this is the generated code for Lion:

package test.component

import zio.schema._

case class Lion(
  eats: Zebra
)
object Lion {

  implicit val codec: Schema[Lion] = DeriveSchema.gen[Lion]

}

but it should have been:

package test.component

import zio.schema._

case class Lion(
  eats: Animal.Zebra
)
object Lion {

  implicit val codec: Schema[Lion] = DeriveSchema.gen[Lion]

}

Since Zebra is nested under Animal:

package test.component

import zio.schema._
import zio.schema.annotation._

@noDiscriminator
sealed trait Animal {
  def age: Int
  def weight: Float
}
object Animal {

  implicit val codec: Schema[Animal] = DeriveSchema.gen[Animal]
  case class Alligator(
    age: Int,
    weight: Float,
    num_teeth: Int
  ) extends Animal
  object Alligator {

    implicit val codec: Schema[Alligator] = DeriveSchema.gen[Alligator]

  }
  case class Zebra(
    age: Int,
    weight: Float,
    num_stripes: Int
  ) extends Animal
  object Zebra {

    implicit val codec: Schema[Zebra] = DeriveSchema.gen[Zebra]

  }
}

Expected behaviour
when subtypes are referenced directly from outside the shared companion, they should prepend the encapsulating path to the type.
If inside the shared companion, then bare reference should be fine: if Lion was part of Animals oneOf => it would have extended same sealed trait, and would have resided inside the companion, thus can (and should) reference Zebra directly.

edge case: make sure inner types don't collide with imported types.

@hochgi hochgi added the bug Something isn't working label May 26, 2024
@hochgi hochgi changed the title [gen] Concrete subtypes of a sum type referenced directly with nesting or proper import [gen] Concrete subtypes of a sum type referenced directly without nesting or proper import May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
1 participant