Skip to content

Instantly share code, notes, and snippets.

@davegurnell
Last active April 20, 2016 15:23
Show Gist options
  • Select an option

  • Save davegurnell/917a623b53b6bb6181256b30d47c9565 to your computer and use it in GitHub Desktop.

Select an option

Save davegurnell/917a623b53b6bb6181256b30d47c9565 to your computer and use it in GitHub Desktop.
Proof-of-concept automatic substitute for Slick's MappedTo, implemented using shapeless' Generic.
import shapeless._
import slick.ast.TypedType
import scala.reflect.ClassTag
trait GenericColumnTypeImplicits {
// This definition summons a column type for a type Pk provided:
// - Pk is a case class with a single field of type Underlying;
// - Slick can summon a column type for Underlying.
//
// It conflicts with MappedTo,
// so you'll have to opt out of MappedTo if you opt into this.
// However, with this definition MappedTo becomes redundant.
//
// The code uses a library called "shapeless"
// that can automatically map between case classes and
// a generic representation called an "HList".
// The "Generic" object here has "to" and "from" methods
// that convert back and forth.
//
// Because we have access to the "gen.from" method,
// we can side-step the problem of not having access
// to the apply method on a companion object.
implicit def idColumnType[Pk, Underlying](
implicit
gen: Generic.Aux[Pk, Underlying :: HNil],
tag: ClassTag[Pk],
tpe: BaseColumnType[Underlying]
): TypedType[Pk] = MappedColumnType.base[Pk, Underlying](
primaryKey => gen.to(primaryKey).head,
underlying => gen.from(underlying :: HNil)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment