Skip to content

Commit fbbd64d

Browse files
committed
Copied the definitions of MappedTo, MappedToBase, Isomorphism and isomorphicType() which had been removed in Slick 3.5.0.
1 parent 5e722df commit fbbd64d

3 files changed

Lines changed: 65 additions & 2 deletions

File tree

unicorn-core/src/main/scala/org/virtuslab/unicorn/Identifiers.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.virtuslab.unicorn
22

3-
import slick.lifted.MappedTo
4-
53
/**
64
* Base trait for implementing ids.
75
* It is existential trait so it can have only defs.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.virtuslab.unicorn
2+
3+
import slick.jdbc.JdbcProfile
4+
5+
import scala.reflect.ClassTag
6+
7+
class IsomorphicColumnTypeConversion(implicit val rtc: JdbcProfile) {
8+
import rtc._
9+
implicit def isomorphicType[A, B](implicit iso: Isomorphism[A, B], ct: ClassTag[A], jt: BaseColumnType[B]): BaseColumnType[A] =
10+
MappedColumnType.base[A, B](iso.map, iso.comap)
11+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.virtuslab.unicorn
2+
3+
import scala.language.experimental.macros
4+
import scala.reflect.macros.blackbox.Context
5+
import scala.util.control.NonFatal
6+
7+
/** An isomorphism between two types that can be used for mapped column types. */
8+
class Isomorphism[A, B](val map: A => B, val comap: B => A)
9+
10+
trait MappedToBase extends Any {
11+
type Underlying
12+
def value: Underlying
13+
}
14+
15+
object MappedToBase {
16+
implicit def mappedToIsomorphism[E <: MappedToBase]: Isomorphism[E, E#Underlying] = macro mappedToIsomorphismMacroImpl[E]
17+
18+
def mappedToIsomorphismMacroImpl[E <: MappedToBase](c: Context)(implicit e: c.WeakTypeTag[E]): c.Expr[Isomorphism[E, E#Underlying]] = {
19+
import c.universe._
20+
// Check that E <: MappedToBase. Due to SI-8351 the macro can be expanded before scalac has
21+
// checked this. The error message here will never be seen because scalac's subsequent bounds
22+
// check fails, overriding our error (or backtracking in implicit search).
23+
if (!(e.tpe <:< c.typeOf[MappedToBase]))
24+
c.abort(c.enclosingPosition, "Work-around for SI-8351 leading to illegal macro-invocation -- You should not see this message")
25+
implicit val eutag = c.TypeTag[E#Underlying](e.tpe.member(TypeName("Underlying")).typeSignatureIn(e.tpe))
26+
val cons = c.Expr[E#Underlying => E](Function(
27+
List(ValDef(Modifiers(Flag.PARAM), TermName("v"), /*Ident(eu.tpe.typeSymbol)*/ TypeTree(), EmptyTree)),
28+
Apply(
29+
Select(New(TypeTree(e.tpe)), termNames.CONSTRUCTOR),
30+
List(Ident(TermName("v"))))))
31+
val res = reify { new Isomorphism[E, E#Underlying](_.value, cons.splice) }
32+
try c.typecheck(res.tree) catch {
33+
case NonFatal(ex) =>
34+
val p = c.enclosingPosition
35+
val msg = "Error typechecking MappedTo expansion: " + ex.getMessage
36+
println(p.source.path + ":" + p.line + ": " + msg)
37+
c.error(c.enclosingPosition, msg)
38+
}
39+
res
40+
}
41+
}
42+
43+
/**
44+
* The base type for automatically mapped column types.
45+
* Extending this type (with a type parameter ``T`` which is already a
46+
* supported column type) lets you use your custom type as a column
47+
* type in the Lifted Embedding. You must provide a constructor that
48+
* takes a single value of the underlying type (same restriction as
49+
* for value classes).
50+
*/
51+
trait MappedTo[T] extends Any with MappedToBase {
52+
type Underlying = T
53+
def value: T
54+
}

0 commit comments

Comments
 (0)