With namespacing gone after #1925, we're quite close to being able to output union types as union types.
The remaining issue is basically this:
The problem is that Scala 3 doesn't generate Mirror for union types, so we can't use typeclass derivation for it: scala/scala3#15279
That's true. But, and I'm on very thin ice here, I think we can write a macro which pattern matches on the union type, picks out all the members and summonAlls Schemas for them.
Then we need to generate some code like this:
type SearchResult = Human | Droid | Starship
given Schema[Any, SearchResult] = Schema.typeUnion[SearchResult]
// which would expand to something like this
given Schema[Any, SearchResult] with {
val _1: Schema[Any, Human] = summon[Schema[Any, Human]]
val _2: Schema[Any, Droid] = summon[Schema[Any, Droid]]
val _3: Schema[Any, Starship] = summon[Schema[Any, Starship]]
val subTypes = List(_1, _2, _3)
def resolve(value: SearchResult): caliban.schema.Step[Any] =
value match {
case x: Human => _1.resolve(x)
case x: Droid => _2.resolve(x)
case x: Starship => _3.resolve(x)
}
def toType(isInput: Boolean, isSubscription: Boolean): caliban.introspection.adt.__Type =
caliban.schema.Types.makeUnion(Some("SearchResult"), None, subTypes.map(_.toType_(isInput, isSubscription)))
}
Originally posted by @oyvindberg in #1925 (comment)
With namespacing gone after #1925, we're quite close to being able to output union types as union types.
The remaining issue is basically this:
That's true. But, and I'm on very thin ice here, I think we can write a macro which pattern matches on the union type, picks out all the members and
summonAllsSchemas for them.Then we need to generate some code like this:
Originally posted by @oyvindberg in #1925 (comment)