Skip to content

Commit

Permalink
Merge pull request #233 from sangria-graphql/fix_ambiguous_implicits
Browse files Browse the repository at this point in the history
fix ambiguous implicits in scala 3
  • Loading branch information
yanns authored Oct 28, 2024
2 parents da2bbf1 + 618183d commit e42adec
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/main/scala/sangria/marshalling/FromInput.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait FromInput[Val] {
def fromResult(node: marshaller.Node): Val
}

object FromInput {
object FromInput extends LowPriorityFromInput {
private object ScalarFromInput extends FromInput[Any] {
val marshaller: CoercedScalaResultMarshaller = CoercedScalaResultMarshaller.default
def fromResult(node: marshaller.Node): marshaller.Node = node
Expand Down Expand Up @@ -59,10 +59,14 @@ object FromInput {

implicit def optionInput[T](implicit ev: FromInput[T]): FromInput[Option[T]] =
ev.asInstanceOf[FromInput[Option[T]]]
implicit def seqInput[T](implicit ev: FromInput[T]): SeqFromInput[T] = new SeqFromInput[T](ev)
implicit def iterableInput[T](implicit ev: FromInput[T]): IterableFromInput[T, Iterable] =
new IterableFromInput[T, Iterable](ev)

trait CoercedScalaResult
trait InputObjectResult
}

trait LowPriorityFromInput {
import FromInput.SeqFromInput
implicit def seqInput[T](implicit ev: FromInput[T]): SeqFromInput[T] = new SeqFromInput[T](ev)
}
73 changes: 73 additions & 0 deletions src/test/scala/sangria/marshalling/FromInputSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package sangria.marshalling

import org.scalatest.wordspec.AnyWordSpec

class FromInputSpec extends AnyWordSpec {

"FromInput" should {
"provide default FromInput for Map[String, Any]" in {
val fromInput = implicitly[FromInput[Map[String, Any]]]

assert(fromInput != null)
}

"provide default FromInput for Seq" in {
import FromInputSpec.FromInputStringInstance.stringFromInput

val fromInput = implicitly[FromInput[Seq[String]]]

assert(fromInput != null)
}

"provide default FromInput for Iterable" in {
import FromInputSpec.FromInputStringInstance.stringFromInput

val fromInput = implicitly[FromInput[Iterable[String]]]

assert(fromInput != null)
}

"provide default FromInput for Option" in {
import FromInputSpec.FromInputStringInstance.stringFromInput

val fromInput = implicitly[FromInput[Option[String]]]

assert(fromInput != null)
}

"provide default FromInput for Option of Seq" in {
import FromInputSpec.FromInputStringInstance.stringFromInput

val fromInput = implicitly[FromInput[Option[Seq[String]]]]

assert(fromInput != null)
}

"resolve covariant Seq" in {
import FromInputSpec.InputType._
import FromInputSpec.FromInputStringInstance.stringFromInput

val fromInput = instance(OptionInputType(SeqInputType(StringInputType)))

assert(fromInput != null)
}
}
}

object FromInputSpec {
object FromInputStringInstance {
implicit val stringFromInput: FromInput[String] = new FromInput[String] {
override val marshaller: ResultMarshaller = CoercedScalaResultMarshaller.default
override def fromResult(node: marshaller.Node): String = "hello"
}
}

trait InputType[+T]
object InputType {
case class OptionInputType[T](t: InputType[T]) extends InputType[Option[T]]
case class SeqInputType[T](t: InputType[T]) extends InputType[Seq[T]]
case object StringInputType extends InputType[String]

def instance[T](t: InputType[T])(implicit fromInput: FromInput[T]): FromInput[T] = fromInput
}
}

0 comments on commit e42adec

Please sign in to comment.