diff options
author | Loic Descotte <loic.descotte@gmail.com> | 2017-11-11 08:04:42 +0100 |
---|---|---|
committer | Loic Descotte <loic.descotte@gmail.com> | 2017-11-11 08:24:30 +0100 |
commit | 2cd897dd1bb05981fac1fc9d61ee32f26a16c35b (patch) | |
tree | c2fb5fa0a884f501e053eb979e6dd0862f54336e /examples/shared/src/main/scala/show.scala | |
parent | efe98a7d0b134415f3da0e7a7c3cb6ca5f2b44c4 (diff) | |
download | magnolia-2cd897dd1bb05981fac1fc9d61ee32f26a16c35b.tar.gz magnolia-2cd897dd1bb05981fac1fc9d61ee32f26a16c35b.tar.bz2 magnolia-2cd897dd1bb05981fac1fc9d61ee32f26a16c35b.zip |
scalajs cross build
Diffstat (limited to 'examples/shared/src/main/scala/show.scala')
-rw-r--r-- | examples/shared/src/main/scala/show.scala | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/examples/shared/src/main/scala/show.scala b/examples/shared/src/main/scala/show.scala new file mode 100644 index 0000000..50b34ee --- /dev/null +++ b/examples/shared/src/main/scala/show.scala @@ -0,0 +1,63 @@ +package magnolia.examples + +import magnolia._ +import scala.language.experimental.macros + +/** shows one type as another, often as a string + * + * Note that this is a more general form of `Show` than is usual, as it permits the return type to + * be something other than a string. */ +trait Show[Out, T] { def show(value: T): Out } + +trait GenericShow[Out] { + + /** the type constructor for new [[Show]] instances + * + * The first parameter is fixed as `String`, and the second parameter varies generically. */ + type Typeclass[T] = Show[Out, T] + + def join(typeName: String, strings: Seq[String]): Out + + /** creates a new [[Show]] instance by labelling and joining (with `mkString`) the result of + * showing each parameter, and prefixing it with the class name */ + def combine[T](ctx: CaseClass[Typeclass, T]): Show[Out, T] = new Show[Out, T] { + def show(value: T) = + if (ctx.isValueClass) { + val param = ctx.parameters.head + param.typeclass.show(param.dereference(value)) + } else { + val paramStrings = ctx.parameters.map { param => + s"${param.label}=${param.typeclass.show(param.dereference(value))}" + } + + join(ctx.typeName.split("\\.").last, paramStrings) + } + } + + /** choose which typeclass to use based on the subtype of the sealed trait */ + def dispatch[T](ctx: SealedTrait[Typeclass, T]): Show[Out, T] = new Show[Out, T] { + def show(value: T): Out = ctx.dispatch(value) { sub => + sub.typeclass.show(sub.cast(value)) + } + } + + /** bind the Magnolia macro to this derivation object */ + implicit def gen[T]: Show[Out, T] = macro Magnolia.gen[T] +} + +/** companion object to [[Show]] */ +object Show extends GenericShow[String] { + + /** show typeclass for strings */ + implicit val string: Show[String, String] = new Show[String, String] { + def show(s: String): String = s + } + + def join(typeName: String, params: Seq[String]): String = + params.mkString(s"$typeName(", ",", ")") + + /** show typeclass for integers */ + implicit val int: Show[String, Int] = new Show[String, Int] { + def show(s: Int): String = s.toString + } +} |