Last active
September 6, 2021 03:56
-
-
Save harrylaou/b5f442d8fe428060e19503c4fd2ab83b to your computer and use it in GitHub Desktop.
Converting case classes to Maps using Shapeless
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.harrylaou | |
import shapeless._ | |
import shapeless.ops.product._ | |
import shapeless.syntax.std.product._ | |
/** | |
* Converting case classes to Maps using Shapeless | |
* | |
* | |
* For nested case classes, (thus nested maps) | |
* check [[http://stackoverflow.com/a/31638390]] | |
* | |
* More about the LabelledGeneric representation | |
* Shapeless : not a tutorial - part 2 [[http://kanaka.io/blog/2015/11/10/shapeless-not-a-tutorial-part-2.html]] | |
* shapeless-for-mortals [[https://github.com/fommil/shapeless-for-mortals]] | |
* | |
*/ | |
case class X(a: Boolean, b: String,c:Int) | |
object X { | |
implicit val lgenX = LabelledGeneric[X] | |
} | |
case class Y(a: String, b: String) | |
object Y { | |
implicit val lgenY = LabelledGeneric[Y] | |
} | |
object ToMapImplicits { | |
implicit class ToMapOps[A <: Product](val a: A) | |
extends AnyVal { | |
def mkMapAny(implicit toMap: ToMap.Aux[A, Symbol, Any]): Map[String, Any] = | |
a.toMap[Symbol, Any] | |
.map { case (k: Symbol, v) => k.name -> v } | |
} | |
implicit class ToMapOps2[A <: Product](val a: A) | |
extends AnyVal { | |
def mkMapString(implicit toMap: ToMap.Aux[A, Symbol, Any]): Map[String, String] = | |
a.toMap[Symbol, Any] | |
.map { case (k: Symbol, v) => k.name -> v.toString } | |
} | |
} | |
object Run extends App { | |
import ToMapImplicits._ | |
val x: X = X(true, "bike",26) | |
val y: Y = Y("first", "second") | |
val anyMapX: Map[String, Any] = x.mkMapAny | |
val anyMapY: Map[String, Any] = y.mkMapAny | |
println("anyMapX = " + anyMapX) | |
println("anyMapY = " + anyMapY) | |
val stringMapX: Map[String, String] = x.mkMapString | |
val stringMapY: Map[String, String] = y.mkMapString | |
println("stringMapX = " + stringMapX) | |
println("stringMapY = " + stringMapY) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment