typesafe configを便利に使うためのライブラリを2つ紹介してみます。
PureConfig
A boilerplate-free library for loading configuration files
amm使います。
$ amm
Loading...
Welcome to the Ammonite Repl 1.4.4
(Scala 2.12.7 Java 1.8.0_144)
If you like Ammonite, please support our development at www.patreon.com/lihaoyi
pureconfigを読み込みます。
@ import $ivy.`com.github.pureconfig::pureconfig:0.10.1`
import $ivy.$
@ import pureconfig.generic.auto._
import pureconfig.generic.auto._
@ import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigFactory
型定義します。
@ {
case class RedisConf(host: String, port: Int)
case class MySQLConf(host: String, port: Int)
case class Conf(mySQLConf: MySQLConf, redisClusterConf: Set[RedisConf])
}
今回はreplなのでapplication.confを置くのではなく、文字列でconfを定義します。
@ val conf = ConfigFactory.parseString("""{ my-sql-conf: { host: "my1", port: 3306 }, redis-cluster-conf: [ { host: "re1", port: 7000 } ] }""")
loadConfigするとEitherで結果がかえってきます。
@ pureconfig.loadConfig[Conf](conf)
res5: Either[pureconfig.error.ConfigReaderFailures, Conf] = Right(Conf(MySQLConf("my1", 3306), Set(RedisConf("re1", 7000))))
便利ですね!
デフォルトだとキーはkebabCaseですが、hintをcamelCaseにしてあげるとcamelでもかけます。
@ import pureconfig._
import pureconfig._
@ implicit def hint[T] = ProductHint[T](ConfigFieldMapping(CamelCase, CamelCase))
@ pureconfig.loadConfig[Conf](conf)
res10: Either[error.ConfigReaderFailures, Conf] = Left(ConfigReaderFailures(ConvertFailure(KeyNotFound("mySQLConf", Set("my-sql-conf")), None, ""), List(ConvertFailure(KeyNotFound("redisClusterConf", Set("redis-cluster-conf")), None, ""))))
sealed traitも対応していて、その中でもenumも対応してました。
@ {
import pureconfig.generic.EnumCoproductHint
sealed trait Season
case object Spring extends Season
case object Summer extends Season
case object Autumn extends Season
case object Winter extends Season
implicit val seasonHint = new EnumCoproductHint[Season]
case class MyConf(list: List[Season])
}
@ loadConfig[MyConf](ConfigFactory.parseString("{ list: [spring, summer, autumn, winter] }"))
res12: Either[error.ConfigReaderFailures, MyConf] = Right(MyConf(List(Spring, Summer, Autumn, Winter)))
便利ですね!
他にもcase classのデフォルト値を使うことができたりするみたいです。
shapelessで型クラスをderiveしてるみたいです。多機能でcatsとか他のライブラリとの親和性も別モジュールで提供してるよう。
ficus
Scala-friendly companion to Typesafe config
まずライブラリを読み込みます。
@ import $ivy.`com.iheart::ficus:1.4.3`
@ import net.ceedubs.ficus.Ficus._
さっき同じやつ使います。
@ {
case class RedisConf(host: String, port: Int)
case class MySQLConf(host: String, port: Int)
case class Conf(mySQLConf: MySQLConf, redisClusterConf: Set[RedisConf])
}
@ import net.ceedubs.ficus.readers.ArbitraryTypeReader._
@ val conf = ConfigFactory.parseString("""{ mySQLConf: { host: "my1", port: 3306 }, redisClusterConf: [ { host: "re1", port: 7000 } ] }""")
@ conf.as[Conf](".")
res11: Conf = Conf(MySQLConf("my1", 3306), Set(RedisConf("re1", 7000)))
こっちのライブラリはmacroで取ってきてるみたいです。
軽量だし実用的にはこっちで十分そう。
おわり