Skip to content

Codegen: Support union types as scala 3 union types #1926

Description

@oyvindberg

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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestserverIssue related to caliban servertoolsIssue related to Caliban tools like code generation or schema comparison

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions