Skip to content

Instantly share code, notes, and snippets.

@frgomes
Last active May 16, 2023 18:12
Show Gist options
  • Save frgomes/add521c71dca324839b74f2cf8dac64d to your computer and use it in GitHub Desktop.
Save frgomes/add521c71dca324839b74f2cf8dac64d to your computer and use it in GitHub Desktop.
Scala - Pattern matching on a runtime class employing ClassTag and stable identifiers
import com.typesafe.config.Config
implicit class ImplicitConfigHelper(val c: Option[Config]) extends AnyVal {
import scala.reflect.ClassTag
import scala.util.control.NonFatal
import ImplicitConfigHelper._
implicit def valueOf[T : ClassTag](prop: String)(implicit ev: ClassTag[T]) : T =
ev.runtimeClass match { // you need stable identifiers here
case String_ => c.get.getString(prop).asInstanceOf[T]
case Int_ => c.get.getInt(prop).asInstanceOf[T]
case Long_ => c.get.getLong(prop).asInstanceOf[T]
case _ => throw new UnsupportedOperationException(s"Unsupported type: ${ev}")
}
implicit def valueOf[T](prop: String, default: => T)(implicit ev: ClassTag[T]) : T =
try {
ev.runtimeClass match { // you need stable identifiers here
case String_ => c.fold(default.asInstanceOf[String])(c => c.getString(prop)).asInstanceOf[T]
case Int_ => c.fold(default.asInstanceOf[Int]) (c => c.getInt(prop)).asInstanceOf[T]
case Long_ => c.fold(default.asInstanceOf[Long]) (c => c.getLong(prop)).asInstanceOf[T]
case _ => throw new UnsupportedOperationException(s"Unsupported type: ${ev}")
}
} catch {
case NonFatal(t) => default
case t: Throwable =>
// unrecoverable errors are... well... unrecoverable
throw t
}
}
object ImplicitConfigHelper {
// declares stable identifiers
val String_ = classOf[String]
val Int_ = classOf[Int]
val Long_ = classOf[Long]
}
@novakov-alexey-zz
Copy link

@frgomes, thanks, it is very useful example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment