Skip to content

Commit

Permalink
Change gen usage (ghostdogpr#1115)
Browse files Browse the repository at this point in the history
* Upgrade Scala 3 to 3.1.0

* Give federation a little help

* Simplify

* Remove weird trick

* Update CI

* Fix name

* Simplify

* Simplify

* fmt

* Simplify

* Add R parameter to gen

* fmt

* Simplify

* Cleanup

* Fix examples

* Cleanup

* Prettify

* Simplify

* Fix federation

* Scala 3 fix

* Proper fix
  • Loading branch information
ghostdogpr authored and Fluxx committed Jan 13, 2022
1 parent 9ef6eee commit d049bc7
Show file tree
Hide file tree
Showing 17 changed files with 105 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import caliban.introspection.adt.{ __Introspection, __Type }
import caliban.schema.Schema

trait IntrospectionDerivation {
implicit lazy val typeSchema: Schema[Any, __Type] = Schema.gen[__Type]
implicit lazy val typeSchema: Schema[Any, __Type] = Schema.gen

val introspectionSchema: Schema[Any, __Introspection] = Schema.gen[__Introspection]
val introspectionSchema: Schema[Any, __Introspection] = Schema.gen
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ trait SchemaDerivation[R] extends LowPriorityDerivedSchema {
* For a case class or sealed trait, you can call `genMacro[T].schema` instead to get more details if the
* schema can't be derived.
*/
def gen[T](implicit derived: Derived[Schema[R, T]]): Schema[R, T] = derived.schema
def gen[R0, T](implicit derived: Derived[Schema[R0, T]]): Schema[R0, T] = derived.schema

}

Expand Down
26 changes: 19 additions & 7 deletions core/src/main/scala-3/caliban/schema/SchemaDerivation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@ import caliban.schema.macros.{ Macros, TypeInfo }
import scala.deriving.Mirror
import scala.compiletime._

trait SchemaDerivation[R] {
object PrintDerived {
import scala.quoted.*
inline def apply[T](inline any: T): T = ${ printDerived('any) }
def printDerived[T: Type](any: Expr[T])(using qctx: Quotes): Expr[T] = {
import qctx.reflect._
println(Printer.TreeShortCode.show(any.asTerm))
any
}
}

trait SchemaDerivation[A] {

/**
* Default naming logic for input types.
Expand All @@ -21,20 +31,20 @@ trait SchemaDerivation[R] {
*/
def customizeInputTypeName(name: String): String = s"${name}Input"

inline def recurse[Label, A <: Tuple](index: Int = 0): List[(String, List[Any], Schema[R, Any], Int)] =
inline def recurse[R, Label, A <: Tuple](index: Int = 0): List[(String, List[Any], Schema[R, Any], Int)] =
inline erasedValue[(Label, A)] match {
case (_: (name *: names), _: (t *: ts)) =>
val label = constValue[name].toString
val annotations = Macros.annotations[t]
val builder = summonInline[Schema[R, t]].asInstanceOf[Schema[R, Any]]
(label, annotations, builder, index) :: recurse[names, ts](index + 1)
(label, annotations, builder, index) :: recurse[R, names, ts](index + 1)
case (_: EmptyTuple, _) => Nil
}

inline def derived[A]: Schema[R, A] =
inline def derived[R, A]: Schema[R, A] =
inline summonInline[Mirror.Of[A]] match {
case m: Mirror.SumOf[A] =>
lazy val members = recurse[m.MirroredElemLabels, m.MirroredElemTypes]()
lazy val members = recurse[R, m.MirroredElemLabels, m.MirroredElemTypes]()
lazy val info = Macros.typeInfo[A]
lazy val annotations = Macros.annotations[A]
lazy val subTypes =
Expand Down Expand Up @@ -112,7 +122,7 @@ trait SchemaDerivation[R] {
}
case m: Mirror.ProductOf[A] =>
lazy val annotations = Macros.annotations[A]
lazy val fields = recurse[m.MirroredElemLabels, m.MirroredElemTypes]()
lazy val fields = recurse[R, m.MirroredElemLabels, m.MirroredElemTypes]()
lazy val info = Macros.typeInfo[A]
lazy val paramAnnotations = Macros.paramAnnotations[A].toMap
new Schema[R, A] {
Expand Down Expand Up @@ -235,5 +245,7 @@ trait SchemaDerivation[R] {
private def getDefaultValue(annotations: Seq[Any]): Option[String] =
annotations.collectFirst { case GQLDefault(v) => v }

inline given gen[A]: Schema[R, A] = derived
inline given gen[R, A]: Schema[R, A] = derived[R, A]

inline def genDebug[R, A]: Schema[R, A] = PrintDerived(derived[R, A])
}
2 changes: 1 addition & 1 deletion core/src/main/scala/caliban/schema/ArgBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ trait ArgBuilder[T] { self =>
def buildMissing(default: Option[String]): Either[ExecutionError, T] =
default
.map(
Parser.parseInputValue(_).flatMap(build(_)).left.map(e => ExecutionError(e.getMessage()))
Parser.parseInputValue(_).flatMap(build).left.map(e => ExecutionError(e.getMessage()))
)
.getOrElse(build(NullValue))

Expand Down
19 changes: 19 additions & 0 deletions core/src/test/scala-3/caliban/Scala3SpecificSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package caliban

import caliban.GraphQL._
import caliban.schema.Annotations.GQLInterface
import zio._
import zio.clock._
import zio.console._
import zio.test.Assertion._
import zio.test._
import zio.test.environment.TestEnvironment
Expand Down Expand Up @@ -69,6 +72,22 @@ object Scala3SpecificSpec extends DefaultRunnableSpec {
assertM(interpreter.flatMap(_.execute(query)).map(_.data.toString))(
equalTo("""{"item":{"a":1}}""")
)
},
testM("Derive R without imports") {
case class Inner(io: RIO[Console, String])
case class Queries(io: RIO[Clock, Int], inner: Inner)
val api = graphQL[Clock with Console, Queries, Unit, Unit](RootResolver(Queries(UIO(1), Inner(UIO("ok")))))
val interpreter = api.interpreter
val query =
"""query {
| io
| inner {
| io
| }
|}""".stripMargin
assertM(interpreter.flatMap(_.execute(query)).map(_.data.toString))(
equalTo("""{"io":1,"inner":{"io":"ok"}}""")
)
}
)
}
2 changes: 1 addition & 1 deletion core/src/test/scala/caliban/TestUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ object TestUtils {
)

object Character {
implicit val schema: Schema[Any, Character] = Schema.gen[Character]
implicit val schema: Schema[Any, Character] = Schema.gen
}

val characters = List(
Expand Down
31 changes: 18 additions & 13 deletions core/src/test/scala/caliban/execution/ExecutionSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,6 @@ object ExecutionSpec extends DefaultRunnableSpec {
// create a custom schema for the Auth Env
object schema extends GenericSchema[Auth]
import schema._
import schema.gen

// effectfully produce a stream using the environment
def getStream(req: Req) = ZStream.fromEffect(for {
Expand All @@ -423,7 +422,13 @@ object ExecutionSpec extends DefaultRunnableSpec {

// set up a wrapped interpreter, setting the authentication token in the auth context
val interpreter =
graphQL(RootResolver(Queries(1), Option.empty[Unit], Subscriptions(getStream))).interpreter
graphQL[Auth, Queries, Unit, Subscriptions](
RootResolver(
queryResolver = Some(Queries(1)),
mutationResolver = Option.empty[Unit],
subscriptionResolver = Some(Subscriptions(getStream))
)
).interpreter
val wrappedInterpreter = for {
auth <- ZIO.service[FiberRef[Option[AuthToken]]]
_ <- auth.set(Some(AuthToken("TOKEN")))
Expand Down Expand Up @@ -489,9 +494,9 @@ object ExecutionSpec extends DefaultRunnableSpec {
case class Query(test: Obj)

object Schemas {
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Union.Child].rename("UnionChild")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen[Union]
implicit val schemaQuery: Schema[Any, Query] = Schema.gen[Query]
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Any, Union.Child].rename("UnionChild")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen
implicit val schemaQuery: Schema[Any, Query] = Schema.gen
}
import Schemas._

Expand Down Expand Up @@ -521,9 +526,9 @@ object ExecutionSpec extends DefaultRunnableSpec {
case class Query(test: Obj)

object Schemas {
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Union.Child].rename("UnionChild")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen[Union].rename("UnionRenamed")
implicit val schemaQuery: Schema[Any, Query] = Schema.gen[Query]
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Any, Union.Child].rename("UnionChild")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen[Any, Union].rename("UnionRenamed")
implicit val schemaQuery: Schema[Any, Query] = Schema.gen
}
import Schemas._

Expand Down Expand Up @@ -554,11 +559,11 @@ object ExecutionSpec extends DefaultRunnableSpec {
case class Query(test: Obj)

object Schemas {
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Union.Child].rename("UnionChild")
implicit val schemaUnionChild: Schema[Any, Union.Child] = Schema.gen[Any, Union.Child].rename("UnionChild")
implicit val schemaUnionChildO: Schema[Any, Union.ChildO.type] =
Schema.gen[Union.ChildO.type].rename("UnionChildO")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen[Union].rename("UnionRenamed")
implicit val schemaQuery: Schema[Any, Query] = Schema.gen[Query]
Schema.gen[Any, Union.ChildO.type].rename("UnionChildO")
implicit val schemaTestUnion: Schema[Any, Union] = Schema.gen[Any, Union].rename("UnionRenamed")
implicit val schemaQuery: Schema[Any, Query] = Schema.gen
}
import Schemas._

Expand Down Expand Up @@ -782,7 +787,7 @@ object ExecutionSpec extends DefaultRunnableSpec {
implicit val schemaHuman: Schema[Any, Character.Human] = Schema.gen
implicit val schemaDroid: Schema[Any, Character.Droid] = Schema.gen
implicit val schemaSearchResult: Schema[Any, SearchResult] = eitherUnionSchema("SearchResult")
implicit val schemaQuery: Schema[Any, Query] = Schema.gen[Query]
implicit val schemaQuery: Schema[Any, Query] = Schema.gen
}

import CustomSchema._
Expand Down
8 changes: 4 additions & 4 deletions core/src/test/scala/caliban/schema/SchemaSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ object SchemaSpec extends DefaultRunnableSpec {

case class A(s: String)
object A {
implicit val aSchema: Schema[Blocking, A] = gen[A]
implicit val aSchema: Schema[Blocking, A] = gen
}
case class B(a: List[Option[A]])

A.aSchema.toType_()

val schema: Schema[Blocking, B] = gen[B]
val schema: Schema[Blocking, B] = gen
}

assert(Types.collectTypes(blockingSchema.schema.toType_()).map(_.name.getOrElse("")))(
Expand Down Expand Up @@ -125,14 +125,14 @@ object SchemaSpec extends DefaultRunnableSpec {
case class Something(b: Int)
case class Query(something: Something)

implicit val somethingSchema: Schema[Any, Something] = Schema.gen[Something].rename("SomethingElse")
implicit val somethingSchema: Schema[Any, Something] = Schema.gen[Any, Something].rename("SomethingElse")

assert(Types.innerType(introspectSubscription[Something]).name)(isSome(equalTo("SomethingElse")))
},
test("union redirect") {
case class Queries(union: RedirectingUnion)

implicit val queriesSchema: Schema[Any, Queries] = Schema.gen[Queries]
implicit val queriesSchema: Schema[Any, Queries] = Schema.gen

val types = Types.collectTypes(introspect[Queries])
val subTypes = types.find(_.name.contains("RedirectingUnion")).flatMap(_.possibleTypes)
Expand Down
11 changes: 6 additions & 5 deletions core/src/test/scala/caliban/wrappers/WrappersSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ object WrappersSpec extends DefaultRunnableSpec {

object schema extends GenericSchema[Clock] {
val interpreter =
(graphQL(RootResolver(Test(clock.sleep(2 minutes).as(0)))) @@ timeout(1 minute)).interpreter
(graphQL[Clock, Test, Unit, Unit](RootResolver(Test(clock.sleep(2 minutes).as(0)))) @@
timeout(1 minute)).interpreter
}

val query = gqldoc("""
Expand All @@ -146,10 +147,10 @@ object WrappersSpec extends DefaultRunnableSpec {
case class Hero(name: URIO[Clock, String], friends: List[Hero] = Nil)

object schema extends GenericSchema[Clock] {
implicit lazy val heroSchema: Schema[Clock, Hero] = schema.gen[Hero]
implicit lazy val heroSchema: Schema[Clock, Hero] = gen

def api(latch: Promise[Nothing, Unit]): GraphQL[Clock] =
graphQL(
graphQL[Clock, Query, Unit, Unit](
RootResolver(
Query(
Hero(
Expand Down Expand Up @@ -196,9 +197,9 @@ object WrappersSpec extends DefaultRunnableSpec {
case class Hero(name: URIO[Clock, String], friends: List[Hero] = Nil)

object schema extends GenericSchema[Clock] {
implicit lazy val heroSchema: Schema[Clock, Hero] = schema.gen[Hero]
implicit lazy val heroSchema: Schema[Clock, Hero] = gen
def api: GraphQL[Clock] =
graphQL(
graphQL[Clock, Query, Unit, Unit](
RootResolver(
Query(
Hero(
Expand Down
12 changes: 5 additions & 7 deletions examples/src/main/scala/example/ExampleApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package example

import example.ExampleData._
import example.ExampleService.ExampleService

import caliban.GraphQL
import caliban.GraphQL.graphQL
import caliban.RootResolver
import caliban.schema.Annotations.{ GQLDeprecated, GQLDescription }
import caliban.schema.GenericSchema
import caliban.schema.{ GenericSchema, Schema }
import caliban.wrappers.ApolloTracing.apolloTracing
import caliban.wrappers.Wrappers._

import zio.URIO
import zio.clock.Clock
import zio.console.Console
Expand All @@ -30,10 +28,10 @@ object ExampleApi extends GenericSchema[ExampleService] {
case class Mutations(deleteCharacter: CharacterArgs => URIO[ExampleService, Boolean])
case class Subscriptions(characterDeleted: ZStream[ExampleService, Nothing, String])

implicit val roleSchema = gen[Role]
implicit val characterSchema = gen[Character]
implicit val characterArgsSchema = gen[CharacterArgs]
implicit val charactersArgsSchema = gen[CharactersArgs]
implicit val roleSchema: Schema[Any, Role] = Schema.gen
implicit val characterSchema: Schema[Any, Character] = Schema.gen
implicit val characterArgsSchema: Schema[Any, CharacterArgs] = Schema.gen
implicit val charactersArgsSchema: Schema[Any, CharactersArgs] = Schema.gen

val api: GraphQL[Console with Clock with ExampleService] =
graphQL(
Expand Down
21 changes: 10 additions & 11 deletions examples/src/main/scala/example/federation/FederatedApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package example.federation

import example.federation.CharacterService.CharacterService
import example.federation.EpisodeService.EpisodeService

import caliban.GraphQL.graphQL
import caliban.federation.{ EntityResolver, federated }
import caliban.federation.tracing.ApolloFederatedTracing
Expand Down Expand Up @@ -47,13 +46,13 @@ object FederatedApi {
case class Mutations(deleteCharacter: CharacterArgs => URIO[CharacterService, Boolean])
case class Subscriptions(characterDeleted: ZStream[CharacterService, Nothing, String])

implicit val roleSchema = gen[Role]
implicit lazy val episodeSchema: Schema[CharacterService, Episode] = gen[Episode]
implicit val characterSchema = gen[Character]
implicit val characterArgsSchema = gen[CharacterArgs]
implicit val charactersArgsSchema = gen[CharactersArgs]
implicit val episodeArgs = gen[EpisodeArgs]
implicit val episodeArgBuilder: ArgBuilder[EpisodeArgs] = ArgBuilder.gen[EpisodeArgs]
implicit val roleSchema: Schema[Any, Role] = Schema.gen
implicit lazy val episodeSchema: Schema[CharacterService, Episode] = Schema.gen
implicit val characterSchema: Schema[CharacterService, Character] = Schema.gen
implicit val characterArgsSchema: Schema[Any, CharacterArgs] = Schema.gen
implicit val charactersArgsSchema: Schema[Any, CharactersArgs] = Schema.gen
implicit val episodeArgs: Schema[Any, EpisodeArgs] = Schema.gen
implicit val episodeArgBuilder: ArgBuilder[EpisodeArgs] = ArgBuilder.gen

val withFederation = federated(
EntityResolver.from[CharacterArgs](args => ZQuery.fromEffect(CharacterService.findCharacter(args.name))),
Expand Down Expand Up @@ -91,9 +90,9 @@ object FederatedApi {
episodes: EpisodesArgs => URIO[EpisodeService, List[Episode]]
)

implicit val episodeArgsSchema = gen[EpisodeArgs]
implicit val episodesArgsSchema = gen[EpisodesArgs]
implicit val episodeSchema = gen[Episode]
implicit val episodeArgsSchema: Schema[Any, EpisodeArgs] = Schema.gen
implicit val episodesArgsSchema: Schema[Any, EpisodesArgs] = Schema.gen
implicit val episodeSchema: Schema[Any, Episode] = Schema.gen

val api: GraphQL[Console with Clock with EpisodeService] =
graphQL(
Expand Down
14 changes: 7 additions & 7 deletions examples/src/main/scala/example/optimizations/NaiveTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ object NaiveTest extends App with GenericSchema[Console] {
)
)

implicit val viewerMetadataSchema: Schema[Any, ViewerMetadata] = Schema.gen[ViewerMetadata]
implicit val tagSchema: Schema[Any, Tag] = Schema.gen[Tag]
implicit val venueSchema: Schema[Any, Venue] = Schema.gen[Venue]
implicit val userArgsSchema: Schema[Any, UserArgs] = Schema.gen[UserArgs]
implicit val sizeArgsSchema: Schema[Any, SizeArgs] = Schema.gen[SizeArgs]
implicit val firstArgsSchema: Schema[Any, FirstArgs] = Schema.gen[FirstArgs]
implicit lazy val user: Schema[Console, User] = gen[User]
implicit val viewerMetadataSchema: Schema[Any, ViewerMetadata] = Schema.gen
implicit val tagSchema: Schema[Any, Tag] = Schema.gen
implicit val venueSchema: Schema[Any, Venue] = Schema.gen
implicit val userArgsSchema: Schema[Any, UserArgs] = Schema.gen
implicit val sizeArgsSchema: Schema[Any, SizeArgs] = Schema.gen
implicit val firstArgsSchema: Schema[Any, FirstArgs] = Schema.gen
implicit lazy val user: Schema[Console, User] = Schema.gen

val resolver = Queries(args => getUser(args.id))
val api = GraphQL.graphQL(RootResolver(resolver))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ object OptimizedTest extends App with GenericSchema[Console] {
def getUpcomingEventIdsForUser(id: Int, first: Int): ConsoleQuery[List[Int]] =
ZQuery.fromRequest(GetUpcomingEventIdsForUser(id, first))(UpcomingEventDataSource)

implicit val viewerMetadataSchema: Schema[Any, ViewerMetadata] = Schema.gen[ViewerMetadata]
implicit val tagSchema: Schema[Any, Tag] = Schema.gen[Tag]
implicit val venueSchema: Schema[Any, Venue] = Schema.gen[Venue]
implicit val userArgsSchema: Schema[Any, UserArgs] = Schema.gen[UserArgs]
implicit val sizeArgsSchema: Schema[Any, SizeArgs] = Schema.gen[SizeArgs]
implicit val firstArgsSchema: Schema[Any, FirstArgs] = Schema.gen[FirstArgs]
implicit lazy val user: Schema[Console, User] = gen[User]
implicit val viewerMetadataSchema: Schema[Any, ViewerMetadata] = Schema.gen
implicit val tagSchema: Schema[Any, Tag] = Schema.gen
implicit val venueSchema: Schema[Any, Venue] = Schema.gen
implicit val userArgsSchema: Schema[Any, UserArgs] = Schema.gen
implicit val sizeArgsSchema: Schema[Any, SizeArgs] = Schema.gen
implicit val firstArgsSchema: Schema[Any, FirstArgs] = Schema.gen
implicit lazy val user: Schema[Console, User] = Schema.gen

val resolver = Queries(args => getUser(args.id))
val api = GraphQL.graphQL(RootResolver(resolver))
Expand Down
Loading

0 comments on commit d049bc7

Please sign in to comment.