Skip to content

Commit

Permalink
Merge pull request #2101 from typelevel/add_read_write_generic_back
Browse files Browse the repository at this point in the history
Add {Write.Read}.generic back to help migrate from earlier versions
  • Loading branch information
jatcwang authored Sep 17, 2024
2 parents f3f249e + 9af12d5 commit b5b234b
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 72 deletions.
11 changes: 4 additions & 7 deletions modules/core/src/main/scala-2/doobie/util/GetPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

}
26 changes: 26 additions & 0 deletions modules/core/src/main/scala-2/doobie/util/MkGetPlatform.scala
Original file line number Diff line number Diff line change
@@ -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)
}

}
26 changes: 26 additions & 0 deletions modules/core/src/main/scala-2/doobie/util/MkPutPlatform.scala
Original file line number Diff line number Diff line change
@@ -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)
}

}
11 changes: 4 additions & 7 deletions modules/core/src/main/scala-2/doobie/util/PutPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

}
3 changes: 3 additions & 0 deletions modules/core/src/main/scala-2/doobie/util/ReadPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
4 changes: 4 additions & 0 deletions modules/core/src/main/scala-2/doobie/util/WritePlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
15 changes: 1 addition & 14 deletions modules/core/src/main/scala-3/doobie/util/GetPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
20 changes: 20 additions & 0 deletions modules/core/src/main/scala-3/doobie/util/MkGetPlatform.scala
Original file line number Diff line number Diff line change
@@ -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)
}
20 changes: 20 additions & 0 deletions modules/core/src/main/scala-3/doobie/util/MkPutPlatform.scala
Original file line number Diff line number Diff line change
@@ -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)
}
15 changes: 1 addition & 14 deletions modules/core/src/main/scala-3/doobie/util/PutPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
5 changes: 3 additions & 2 deletions modules/core/src/main/scala/doobie/util/get.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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](
Expand Down
5 changes: 3 additions & 2 deletions modules/core/src/main/scala/doobie/util/put.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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](
Expand Down
25 changes: 13 additions & 12 deletions modules/core/src/test/scala-2/doobie/util/GetSuitePlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}

}
19 changes: 5 additions & 14 deletions modules/core/src/test/scala-2/doobie/util/PutSuitePlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ object TestClasses {

case class CCIntString(i: Int, s: String)

case class CCAnyVal(s: String) extends AnyVal

object PlainObj
}

0 comments on commit b5b234b

Please sign in to comment.