I'm building a librairy to give access to several catalog of data. A catalog can refer to a database and the associated tables defined in configuration files (HOCON). Here is a config file example (book.conf):
author {
database = "db_books"
table = "author"
}
book {
database = "db_books"
table = "book"
}
I define a case class representing this config file (BookCatalogConfig.scala):
trait CatalogConfig
case class TableConfig(database: String, table: String)
case class BookCatalogConfig(author: TableConfig, book: TableConfig) extends CatalogConfig
Then I define my BookCatalog like that:
case class BookCatalog(environment: String) {
/* ... */
val config: BookCatalogConfig = CatalogConfigLoader[BookCatalogConfig](environment).load()
/* ... */
}
And my CatalogConfigLoader utility:
case class CatalogConfigLoader[A <: CatalogConfig](environment: String) {
def load(): A = {
import pureconfig.generic.auto._
// Note: ConfigHelper.getConfig(environment) return a Typesafe Config object with the content of book.conf)
ConfigSource.fromConfig(ConfigHelper.getConfig(environment)).load[A] match {
case Right(catalogConfig: A) => catalogConfig
case Left(error: ConfigReaderFailures) => throw new Exception(error.toString())
}
}
}
But this doesn't compile with an error: Cannot find an implicit instance of pureconfig.ConfigReader[A].
If you are trying to read or write a case class or sealed trait consider using PureConfig's auto derivation by adding import pureconfig.generic.auto._
I've already read a lot on the subject, but no solution has worked
Note: I'm using Pureconfig 0.14 for scala 2.11 (I cannot upgade because 0.14 is the last one for scala 2.11... and I cannot upgrade the scala version too...).
The solution is (thanks to Luis Miguel and Matthias), with some rework:
object CatalogConfigLoader {
def load[A <: CatalogConfig : ConfigReader : ClassTag](environment: Environment): A = {
ConfigSource.fromConfig(ConfigHelper.getConfig(environment.filepath)).load[A] match {
case Right(catalogConfig: A) => catalogConfig
case Left(error: ConfigReaderFailures) => throw new Exception(error.toString())
}
}