Skip to content

Instantly share code, notes, and snippets.

@frgomes
Last active November 27, 2022 02:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save frgomes/acb9fc2df3495d3f59ffda26102110be to your computer and use it in GitHub Desktop.
Save frgomes/acb9fc2df3495d3f59ffda26102110be to your computer and use it in GitHub Desktop.
Scala - Obtain structure of a case class and build an instance of it from data
// NOTE: This trickery below allows us to obtain the type of
// fields of a case class, so that we can play with generic
// pattern matching on field types.
// The post below is somewhat related.
// See also: http://www.alessandrolacava.com/blog/scala-case-classes-in-depth/
import scala.reflect.runtime.universe._
def classAccessors[T: TypeTag]: List[MethodSymbol] =
typeOf[T].members
.sorted.collect {
case m: MethodSymbol if m.isCaseAccessor => m
}.toList
def classFactory[T: TypeTag]: Option[MethodSymbol] =
typeOf[T].members
.collect {
case m: MethodSymbol if m.isPrimaryConstructor => m
}.headOption
//----- Example of usage -----
case class User(name: String, position: String, salary: Float, age: Int)
val factory: Option[MethodSymbol] = classFactory[User]
val accessors: List[MethodSymbol] = classAccessors[User]
val values: List[Any] = List("John Smith", "Manager", 85605.50, 36)
// factory: Option[MethodSymbol] = Some(constructor User)
// accessors: List[MethodSymbol] = List(value name, value position, value salary, value age)
// values: List[Any] = List(John Smith, Manager, 85605.5, 36)
val types = accessors.map(m => m.returnType)
// types: List[Type] = List(String, String, scala.Float, scala.Int)
val check = (values zip types).map { case (v, t) => (v.getClass.getSimpleName, t.toString) }
// check: List[(String, String)] = List(
// ("String", "String"),
// ("String", "String"),
// ("Double", "scala.Float"),
// ("Integer", "scala.Int")
// )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment