diff --git a/modules/core/src/main/scala-2/doobie/util/GetPlatform.scala b/modules/core/src/main/scala-2/doobie/util/GetPlatform.scala index 0274fe4d4..0967c24f0 100644 --- a/modules/core/src/main/scala-2/doobie/util/GetPlatform.scala +++ b/modules/core/src/main/scala-2/doobie/util/GetPlatform.scala @@ -4,23 +4,20 @@ package doobie.util -import shapeless._ +import shapeless.* import shapeless.ops.hlist.IsHCons trait GetPlatform { import doobie.util.compat.=:= /** @group Instances */ - implicit def unaryProductGet[A, L <: HList, H, T <: HList]( + @deprecated("Use Get.derived instead to derive instances explicitly", "1.0.0-RC6") + def unaryProductGet[A, L <: HList, H, T <: HList]( implicit G: Generic.Aux[A, L], C: IsHCons.Aux[L, H, T], H: Lazy[Get[H]], E: (H :: HNil) =:= L - ): MkGet[A] = { - void(C) // C drives inference but is not used directly - val get = H.value.tmap[A](h => G.from(h :: HNil)) - MkGet.lift(get) - } + ): MkGet[A] = MkGet.unaryProductGet } diff --git a/modules/core/src/main/scala-2/doobie/util/MkGetPlatform.scala b/modules/core/src/main/scala-2/doobie/util/MkGetPlatform.scala new file mode 100644 index 000000000..1a805d0e1 --- /dev/null +++ b/modules/core/src/main/scala-2/doobie/util/MkGetPlatform.scala @@ -0,0 +1,26 @@ +// Copyright (c) 2013-2020 Rob Norris and Contributors +// This software is licensed under the MIT License (MIT). +// For more information see LICENSE or https://opensource.org/licenses/MIT + +package doobie.util + +import shapeless._ +import shapeless.ops.hlist.IsHCons + +trait MkGetPlatform { + import doobie.util.compat.=:= + + /** @group Instances */ + implicit def unaryProductGet[A, L <: HList, H, T <: HList]( + implicit + G: Generic.Aux[A, L], + C: IsHCons.Aux[L, H, T], + H: Lazy[Get[H]], + E: (H :: HNil) =:= L + ): MkGet[A] = { + void(C) // C drives inference but is not used directly + val get = H.value.tmap[A](h => G.from(h :: HNil)) + MkGet.lift(get) + } + +} diff --git a/modules/core/src/main/scala-2/doobie/util/MkPutPlatform.scala b/modules/core/src/main/scala-2/doobie/util/MkPutPlatform.scala new file mode 100644 index 000000000..2a4d32c3b --- /dev/null +++ b/modules/core/src/main/scala-2/doobie/util/MkPutPlatform.scala @@ -0,0 +1,26 @@ +// Copyright (c) 2013-2020 Rob Norris and Contributors +// This software is licensed under the MIT License (MIT). +// For more information see LICENSE or https://opensource.org/licenses/MIT + +package doobie.util + +import shapeless._ +import shapeless.ops.hlist.IsHCons + +trait MkPutPlatform { + import doobie.util.compat.=:= + + /** @group Instances */ + implicit def unaryProductPut[A, L <: HList, H, T <: HList]( + implicit + G: Generic.Aux[A, L], + C: IsHCons.Aux[L, H, T], + H: Lazy[Put[H]], + E: (H :: HNil) =:= L + ): MkPut[A] = { + void(E) // E is a necessary constraint but isn't used directly + val put = H.value.contramap[A](a => G.to(a).head) + MkPut.lift(put) + } + +} diff --git a/modules/core/src/main/scala-2/doobie/util/PutPlatform.scala b/modules/core/src/main/scala-2/doobie/util/PutPlatform.scala index 9b946f158..26e3c5cf5 100644 --- a/modules/core/src/main/scala-2/doobie/util/PutPlatform.scala +++ b/modules/core/src/main/scala-2/doobie/util/PutPlatform.scala @@ -4,23 +4,20 @@ package doobie.util -import shapeless._ +import shapeless.* import shapeless.ops.hlist.IsHCons trait PutPlatform { import doobie.util.compat.=:= /** @group Instances */ - implicit def unaryProductPut[A, L <: HList, H, T <: HList]( + @deprecated("Use Put.derived instead to derive instances explicitly", "1.0.0-RC6") + def unaryProductPut[A, L <: HList, H, T <: HList]( implicit G: Generic.Aux[A, L], C: IsHCons.Aux[L, H, T], H: Lazy[Put[H]], E: (H :: HNil) =:= L - ): MkPut[A] = { - void(E) // E is a necessary constraint but isn't used directly - val put = H.value.contramap[A](a => G.to(a).head) - MkPut.lift(put) - } + ): MkPut[A] = MkPut.unaryProductPut } diff --git a/modules/core/src/main/scala-2/doobie/util/ReadPlatform.scala b/modules/core/src/main/scala-2/doobie/util/ReadPlatform.scala index 44d4a4b65..64a5e7371 100644 --- a/modules/core/src/main/scala-2/doobie/util/ReadPlatform.scala +++ b/modules/core/src/main/scala-2/doobie/util/ReadPlatform.scala @@ -29,4 +29,7 @@ trait ReadPlatform { MkRead.ogeneric[A, Repr] } + @deprecated("Use Read.derived instead to derive instances explicitly", "1.0.0-RC6") + def generic[T, Repr](implicit gen: Generic.Aux[T, Repr], G: Lazy[MkRead[Repr]]): MkRead[T] = + MkRead.generic[T, Repr] } diff --git a/modules/core/src/main/scala-2/doobie/util/WritePlatform.scala b/modules/core/src/main/scala-2/doobie/util/WritePlatform.scala index 60fc9fb32..0553067d2 100644 --- a/modules/core/src/main/scala-2/doobie/util/WritePlatform.scala +++ b/modules/core/src/main/scala-2/doobie/util/WritePlatform.scala @@ -27,4 +27,8 @@ trait WritePlatform { val _ = isTuple MkWrite.ogeneric[A, Repr] } + + @deprecated("Use Write.derived instead to derive instances explicitly", "1.0.0-RC6") + def generic[T, Repr](implicit gen: Generic.Aux[T, Repr], A: Lazy[MkWrite[Repr]]): MkWrite[T] = + MkWrite.generic[T, Repr] } diff --git a/modules/core/src/main/scala-3/doobie/util/GetPlatform.scala b/modules/core/src/main/scala-3/doobie/util/GetPlatform.scala index 7011a60c8..74843014c 100644 --- a/modules/core/src/main/scala-3/doobie/util/GetPlatform.scala +++ b/modules/core/src/main/scala-3/doobie/util/GetPlatform.scala @@ -4,17 +4,4 @@ package doobie.util -import scala.deriving.Mirror - -trait GetPlatform: - - // Get is available for single-element products. - given x[P <: Product, A]( - using - p: Mirror.ProductOf[P], - i: p.MirroredElemTypes =:= (A *: EmptyTuple), - g: Get[A] - ): MkGet[P] = { - val get = g.map(a => p.fromProduct(a *: EmptyTuple)) - MkGet.lift(get) - } +trait GetPlatform {} diff --git a/modules/core/src/main/scala-3/doobie/util/MkGetPlatform.scala b/modules/core/src/main/scala-3/doobie/util/MkGetPlatform.scala new file mode 100644 index 000000000..833dbcabc --- /dev/null +++ b/modules/core/src/main/scala-3/doobie/util/MkGetPlatform.scala @@ -0,0 +1,20 @@ +// Copyright (c) 2013-2020 Rob Norris and Contributors +// This software is licensed under the MIT License (MIT). +// For more information see LICENSE or https://opensource.org/licenses/MIT + +package doobie.util + +import scala.deriving.Mirror + +trait MkGetPlatform: + + // Get is available for single-element products. + given unaryProductGet[P <: Product, A]( + using + p: Mirror.ProductOf[P], + i: p.MirroredElemTypes =:= (A *: EmptyTuple), + g: Get[A] + ): MkGet[P] = { + val get = g.map(a => p.fromProduct(a *: EmptyTuple)) + MkGet.lift(get) + } diff --git a/modules/core/src/main/scala-3/doobie/util/MkPutPlatform.scala b/modules/core/src/main/scala-3/doobie/util/MkPutPlatform.scala new file mode 100644 index 000000000..9c9afcacb --- /dev/null +++ b/modules/core/src/main/scala-3/doobie/util/MkPutPlatform.scala @@ -0,0 +1,20 @@ +// Copyright (c) 2013-2020 Rob Norris and Contributors +// This software is licensed under the MIT License (MIT). +// For more information see LICENSE or https://opensource.org/licenses/MIT + +package doobie.util + +import scala.deriving.Mirror + +trait MkPutPlatform: + + // Put is available for single-element products. + given unaryProductPut[P <: Product, A]( + using + m: Mirror.ProductOf[P], + i: m.MirroredElemTypes =:= (A *: EmptyTuple), + p: Put[A] + ): MkPut[P] = { + val put: Put[P] = p.contramap(p => i(Tuple.fromProductTyped(p)).head) + MkPut.lift(put) + } diff --git a/modules/core/src/main/scala-3/doobie/util/PutPlatform.scala b/modules/core/src/main/scala-3/doobie/util/PutPlatform.scala index 60ffa7b29..9a7151ebe 100644 --- a/modules/core/src/main/scala-3/doobie/util/PutPlatform.scala +++ b/modules/core/src/main/scala-3/doobie/util/PutPlatform.scala @@ -4,17 +4,4 @@ package doobie.util -import scala.deriving.Mirror - -trait PutPlatform: - - // Put is available for single-element products. - given [P <: Product, A]( - using - m: Mirror.ProductOf[P], - i: m.MirroredElemTypes =:= (A *: EmptyTuple), - p: Put[A] - ): MkPut[P] = { - val put: Put[P] = p.contramap(p => i(Tuple.fromProductTyped(p)).head) - MkPut.lift(put) - } +trait PutPlatform {} diff --git a/modules/core/src/main/scala/doobie/util/get.scala b/modules/core/src/main/scala/doobie/util/get.scala index bbfeb45b9..e1a9557b1 100644 --- a/modules/core/src/main/scala/doobie/util/get.scala +++ b/modules/core/src/main/scala/doobie/util/get.scala @@ -80,7 +80,7 @@ sealed abstract class Get[A]( } -object Get extends GetInstances { +object Get extends GetInstances with GetPlatform { def apply[A](implicit ev: Get[A]): ev.type = ev @@ -221,7 +221,8 @@ sealed abstract class MkGet[A]( override val vendorTypeNames: List[String], override val get: Coyoneda[(ResultSet, Int) => *, A] ) extends Get[A](typeStack, jdbcSources, jdbcSourceSecondary, vendorTypeNames, get) -object MkGet extends GetPlatform { + +object MkGet extends MkGetPlatform { def lift[A](g: Get[A]): MkGet[A] = new MkGet[A]( diff --git a/modules/core/src/main/scala/doobie/util/put.scala b/modules/core/src/main/scala/doobie/util/put.scala index 93a0d5a09..2588c8ce9 100644 --- a/modules/core/src/main/scala/doobie/util/put.scala +++ b/modules/core/src/main/scala/doobie/util/put.scala @@ -82,7 +82,7 @@ sealed abstract class Put[A]( } -object Put extends PutInstances { +object Put extends PutInstances with PutPlatform { def apply[A](implicit ev: Put[A]): ev.type = ev @@ -234,7 +234,8 @@ sealed abstract class MkPut[A]( override val put: ContravariantCoyoneda[(PreparedStatement, Int, *) => Unit, A], override val update: ContravariantCoyoneda[(ResultSet, Int, *) => Unit, A] ) extends Put[A](typeStack, jdbcTargets, vendorTypeNames, put, update) -object MkPut extends PutPlatform { + +object MkPut extends MkPutPlatform { def lift[A](g: Put[A]): MkPut[A] = new MkPut[A]( diff --git a/modules/core/src/test/scala-2/doobie/util/GetSuitePlatform.scala b/modules/core/src/test/scala-2/doobie/util/GetSuitePlatform.scala index 1f40b8ef9..a6daa5f06 100644 --- a/modules/core/src/test/scala-2/doobie/util/GetSuitePlatform.scala +++ b/modules/core/src/test/scala-2/doobie/util/GetSuitePlatform.scala @@ -3,26 +3,27 @@ // For more information see LICENSE or https://opensource.org/licenses/MIT package doobie.util -import doobie.testutils.VoidExtensions - -object GetSuitePlatform { - final case class Y(x: String) extends AnyVal - final case class P(x: Int) extends AnyVal -} +import doobie.testutils.{VoidExtensions, assertContains} +import doobie.testutils.TestClasses.{CCIntString, PlainObj, CCAnyVal} trait GetSuitePlatform { self: munit.FunSuite => - import GetSuitePlatform._ test("Get can be auto derived for unary products (AnyVal)") { - import doobie.generic.auto._ + import doobie.generic.auto.* - Get[Y].void - Get[P].void + Get[CCAnyVal].void } test("Get can be explicitly derived for unary products (AnyVal)") { - Get.derived[Y].void - Get.derived[P].void + Get.derived[CCAnyVal].void + } + + test("Get should not be derived for non-unary products") { + import doobie.generic.auto.* + + assertContains(compileErrors("Get[CCIntString]"), "implicit value") + assertContains(compileErrors("Get[(Int, Int)]"), "implicit value") + assertContains(compileErrors("Get[PlainObj.type]"), "implicit value") } } diff --git a/modules/core/src/test/scala-2/doobie/util/PutSuitePlatform.scala b/modules/core/src/test/scala-2/doobie/util/PutSuitePlatform.scala index 3237f6bf5..a7eda5bed 100644 --- a/modules/core/src/test/scala-2/doobie/util/PutSuitePlatform.scala +++ b/modules/core/src/test/scala-2/doobie/util/PutSuitePlatform.scala @@ -4,30 +4,21 @@ package doobie.util import doobie.testutils.{VoidExtensions, assertContains} - -object PutSuitePlatform { - final case class Y(x: String) extends AnyVal - final case class P(x: Int) extends AnyVal -} +import doobie.testutils.TestClasses.{CCIntString, PlainObj, CCAnyVal} trait PutSuitePlatform { self: munit.FunSuite => - import PutSuitePlatform._ - test("Put can be auto derived for unary products (AnyVal)") { - import doobie.generic.auto._ + import doobie.generic.auto.* - Put[Y].void - Put[P].void + Put[CCAnyVal].void } test("Put can be explicitly derived for unary products (AnyVal)") { - Put.derived[Y].void - Put.derived[P].void + Put.derived[CCAnyVal].void } test("Put should not be derived for non-unary products") { - import doobie.generic.auto._ - import doobie.testutils.TestClasses.{CCIntString, PlainObj} + import doobie.generic.auto.* assertContains(compileErrors("Put[CCIntString]"), "implicit value") assertContains(compileErrors("Put[(Int, Int)]"), "implicit value") diff --git a/modules/testutils/src/test/scala/doobie/testutils/TestClasses.scala b/modules/testutils/src/test/scala/doobie/testutils/TestClasses.scala index c39e21269..27fe46061 100644 --- a/modules/testutils/src/test/scala/doobie/testutils/TestClasses.scala +++ b/modules/testutils/src/test/scala/doobie/testutils/TestClasses.scala @@ -16,5 +16,7 @@ object TestClasses { case class CCIntString(i: Int, s: String) + case class CCAnyVal(s: String) extends AnyVal + object PlainObj }