Argus
Argus copied to clipboard
Eliminate intermediary "*Union" wrappers for object-typed oneOf traits
The following schema:
{
"$ref": "#/definitions/FooBar",
"definitions": {
"FooBar": {
"oneOf": [
{ "$ref": "#/definitions/Foo" },
{ "$ref": "#/definitions/Bar" }
]
},
"Foo": {
"type": "object",
"properties": {
"foo": {
"type": "string"
}
}
},
"Bar": {
"type": "object",
"properties": {
"bar": {
"type": "integer"
}
}
}
}
}
will yield this:
sealed trait FooBarUnion
case class FooBarFoo(x: Foo) extends FooBarUnion
case class FooBarBar(x: Bar) extends FooBarUnion
case class Foo(foo: Option[String] = None)
case class Bar(bar: Option[Int] = None)
It would be nice if the intermediary wrappers could be eliminated and this could be simplified to:
sealed trait FooBarUnion
case class Foo(foo: Option[String] = None) extends FooBarUnion
case class Bar(bar: Option[Int] = None) extends FooBarUnion
An alternative (and simpler) approach could be to instead generate implicit converter functions between the union case class and the wrapped type. E.g.:
sealed trait FooBarUnion
case class FooBarFoo(x: Foo) extends FooBarUnion
implicit def ToFooBarFoo(x: Foo): FooBarFoo = FooBarFoo(x)
implicit def FromFooBarFoo(x: FooBarFoo): Foo = x.x
case class FooBarBar(x: Bar) extends FooBarUnion
implicit def ToFooBarBar(x: Bar): FooBarBar = FooBarBar(x)
implicit def FromFooBarBar(x: FooBarBar): Bar = x.x
case class Foo(foo: Option[String] = None)
case class Bar(bar: Option[Int] = None)
That way the client code won't usually need to be aware that there are wrapper types at all.