Skip to content

Instantly share code, notes, and snippets.

@lombardo-chcg
Created February 23, 2019 00:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lombardo-chcg/aa49ce46fb6a0206c9611f7c09f96f5d to your computer and use it in GitHub Desktop.
Save lombardo-chcg/aa49ce46fb6a0206c9611f7c09f96f5d to your computer and use it in GitHub Desktop.
a shapeless-powered type class to generate random case class instances
// ammonite import
import $ivy.`com.chuusai:shapeless_2.12:2.3.3`
import shapeless.{Generic, ::, HList, HNil}
// part 1: define the type class
trait RandomData[A] {
def random: A
}
// part 2: define instances for concrete types
object RandomDataInstances {
implicit object RandomInt extends RandomData[Int] {
def random: Int = {
scala.util.Random.nextInt(100000)
}
}
implicit object RandomLong extends RandomData[Long] {
def random: Long = {
Math.abs(scala.util.Random.nextLong())
}
}
implicit object RandomString extends RandomData[String] {
def random: String = {
scala.util.Random.alphanumeric.take(10).mkString
}
}
implicit object RandomBool extends RandomData[Boolean] {
def random: Boolean = {
scala.util.Random.nextBoolean()
}
}
implicit def randomOpt[T]
(implicit
tRandom: RandomData[T]
): RandomData[Option[T]] = new RandomData[Option[T]] {
def random: Option[T] = if (RandomBool.random) Some(tRandom.random) else None
}
implicit def randomHListCons[H, T <: HList]
(implicit
hRandom: RandomData[H],
tRandom: RandomData[T]
): RandomData[H :: T] = {
new RandomData[H :: T] {
def random: ::[H, T] = hRandom.random :: tRandom.random
}
}
implicit object RandomHNil extends RandomData[HNil] {
def random: HNil = HNil
}
implicit def randomGeneric[T, Repr]
(implicit
generic: Generic.Aux[T,Repr],
randomData: RandomData[Repr]
): RandomData[T] = {
new RandomData[T] {
def random: T = generic.from(randomData.random)
}
}
}
// part 3: define an api
object RandomDataApi {
def random[T](implicit randomData: RandomData[T]): T = {
randomData.random
}
}
// part 4: usage examples
import RandomDataInstances._
import RandomDataApi._
random[Int]
random[String]
random[Option[Long]]
case class Car(isRunning: Boolean, maxSpeed: Int, vin: String)
case class Oven(isOn: Boolean, maxTemp: Int, serialNumber: String)
type TupleExample = (String, Long, Int)
random[Car]
random[Oven]
random[TupleExample]
case class HasOptions(a: Option[String], b: Option[Int], c: Option[Long])
random[HasOptions]
case class `A to Z`(
a: Boolean,
b: Int,
c: String,
d: Boolean,
e: Int,
f: String,
h: Boolean,
i: Int,
j: String,
k: Boolean,
l: Int,
m: String,
n: Int,
o: String,
p: Boolean,
q: Int,
r: String,
s: String,
t: Boolean,
u: Int,
v: String,
w: Boolean,
x: Int,
y: String,
z: Int
)
random[`A to Z`]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment