typesafe configの設定パスをscalaのコードで表現する
ScalaMatsuriの感想ブログです
ScalaMatsuriでscala.metaの話を2つ聞いて面白そうと思ったので私もやってみました。 typesafe configをscala.metaとscalameta/paradiseのmacro annotationで設定パスを文字列ではなくscalaのコードで表現できるようにしたやつです。
こんな感じで使います。
// src/main/resources/application.conf akka { actor { serializers { akka-containers = "akka.remote.serialization.MessageContainerSerializer" } } }
import com.typesafe.config.ConfigFactory import com.github.tototoshi.configpath.compile @compile("src/main/resources/application.conf") object path object Example { def main(args: Array[String]): Unit = { val config = ConfigFactory.load() val serializer1 = config.getString( path.akka.actor.serializers.`akka-containers`.full) val serializer2 = config.getString( "akka.actor.serializers.akka-containers") assert(serializer1 == serializer2) } }
objectかclassにcompileアノテーションをつけて、typesafe configの設定ファイルパスを渡すとmacroでコードを生成します。 上記のような設定ファイルがあった時、次のコードは
@compile("src/main/resources/application.conf") object path
次のように展開されています。
object path { abstract class ConfigTree(val name: String, val full: String) object `akka` extends ConfigTree("akka", "akka") { object `actor` extends ConfigTree("actor", "akka.actor") { object `serializers` extends ConfigTree("serializers", "akka.actor.serializers") { object `akka-containers` extends ConfigTree("akka-containers", "akka.actor.serializers.akka-containers") } } } }
これで設定の名前を間違えることがなくなりました。すごい。IntelliJがマクロに弱くて赤くなるけどね。IntelliJが追いついて補完が効くようになれば意外と便利かもしれない。