-
Notifications
You must be signed in to change notification settings - Fork 400
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] fix for codegen of sumtypes with reusable fields #2850
[gen] fix for codegen of sumtypes with reusable fields #2850
Conversation
zio-http-gen/src/test/scala/zio/http/gen/scala/CodeGenSpec.scala
Outdated
Show resolved
Hide resolved
@hochgi Thanks for your contribution. And this contains 100% a crucial bugfix. I also remember, that I had a reason for generating the types twice. Once in the sealed trait hierarchy and once separate. But I forgot the reason. I'll think about it and if I can' remember, we might try it with your way. I like the idea of generating only what is actually used. Even though I think having unused types defined is not good, you can't force anyone (especially not public apis) |
@987Nabil can you show me how we can define in OpenAPI this example zoo endpoint such that I looked at how to do that, and the reusable component was the best I could find. Of course I'll remove the trait body generation ad requested. If not too hard, perhaps I can chanhe this PR to do it the right way :) |
@hochgi The best way would probably be a construct like having an animal type, that has three fields: |
@987Nabil I agree, and if I were to design the API I'm dealing with, that's how I'd do it. EDIT: Note that in the official docs, a similar approach is described: Perhaps we can:
In this zoo toy example, it could look like: trait AnimalSharedFields {
def age: Int
def weight: Float
}
object AnimalSharedFields {
// "Bare" or any other arbitrary name
case class Bare (age: Int, weight: Float) extends AnimalSharedFields
} And sealed trait Animal { this: AnimalSharedFields =>
}
object Animal {
case class Alligator (age: Int, weight: Float, num_teeth: Int) extends Animal with AnimalSharedFields
case class Zebra (age: Int, weight: Float, num_stripes: Int) extends Animal with AnimalSharedFields
} |
@hochgi I feel this suggestion is too complex and idk if this will be useful for most users of the code generator. I would say the default behaviour is
And opt-in to
So basically, your original proposal, but the accessors on the sealed trait are opt in. I am also not sure, what you are doing actually. Because it seems on the one hand like you can define things in the open api spec, but you said you have to impl. against a given endpoint. So just some thoughts I had
|
@987Nabil yes, in hindsight it is a bit complex. Might be worth just adding validations such as to not require optional fields (if config flag enabled), or if same field is declared with a different type (perhaps in a separate reusable object), etc'... But for this PR we can start with just the config :) My motivation: |
zio-http-gen/src/main/scala/zio/http/gen/openapi/EndpointGen.scala
Outdated
Show resolved
Hide resolved
zio-http-gen/src/main/scala/zio/http/gen/openapi/EndpointGen.scala
Outdated
Show resolved
Hide resolved
ef0d570
to
9ea7c1d
Compare
…t actually extend the sealed trait. Sum types abstract members generation by reusable components in the schema, as an opt-in, configurable feature. Only generating sealed trait body if all subtypes include same reusable component, with it's fields as the abstract trait's members. Redundant duplicate classes for each case is now omitted. Validate fields in case classes and traits does not contain duplicates that cannot be reconciled. Existing tests has been amended to reflect the fix. New tests were added. Some utilities were added.
9ea7c1d
to
b855ad7
Compare
) | ||
|
||
lazy val config: zio.Config[Config] = | ||
zc.boolean("common-fields-on-super-type") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please no cryptic renaming. Better use the full path zio.Config.boolean
Head branch was pushed to by a user without write access
fixes #2847
I added a test, initially failing (for the payload in the original issue):
Then fixed it, and even extended it to generate abstract fields from a reusable component, e.g:
zio-http/zio-http-gen/src/test/resources/ComponentAnimal.scala
Lines 7 to 34 in fc51bd7
This PR also avoids generating duplicate copies of the sealed trait subtypes in separate files.