Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ambiguous implicits in scala 3 #233

Merged
merged 1 commit into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
}