scalatypesafe-configpureconfig

could not find implicit value for parameter reader: pureconfig.ConfigReader[T]


Could it be even possible to create the following method with the following level of abstraction with Typesafe Config and pureconfig in scala ? I am aware for defined Case Classes that Config Reader has to be specified as follows , because of the following limitations ... but what about Any Type of Case class ... if they all have their ConfigReaders implemented ?

    /**
      * @param path the.path.to.the.branch
      * @param config the com.typesafe.config obj
      * @tparam T - the type of the case class obj
      * @return the filled-in obj of type T
      *
      */
    def getConfigType[T](path: String, config :Config) :Option[T] = {

      val renderOpts = ConfigRenderOptions.defaults
        .setOriginComments(false).setComments(false).setJson(true)
      val levelConfig :Config = config.getConfig(path)
      val strConfig: String = config.getConfig(path).root().render(renderOpts)

      loadConfig[T](ConfigFactory.parseString(strConfig)) match {
        case Right(objFilledCaseClass) => Some(objFilledCaseClass)
        case Left(errors) => throw new RuntimeException(s"Invalid configuration: $errors")
      }
    }
  }

Solution

  • I assume that you get build time error like "Error:(17, 18) could not find implicit value for parameter reader: pureconfig.ConfigReader[T] loadConfig[T]... "

    Error is that pureconfig's loadConfig method does not find implicit value for it's reader parameter. One solution is to give implicit reader parameter explicitly. Your method getConfigType can take implicit reader as parameter, so that getConfigType interface would behave like loadConfig is behaving.

    So the solution would be define interface as:

    import pureconfig.{ConfigReader, loadConfig}
    // Is there a reason why return type is Option? Method either returns Some or throws exception
    def getConfigType[ConfigType](path: String, config :Config)(implicit reader: ConfigReader[ConfigType]):ConfigType = 
    {
    ...
    loadConfig(ConfigFactory.parseString(strConfig))(reader) match {
    ...
    }
    ...
    }
    

    Then you call it:

    case class YourCustomType()
    import eu.timepit.refined.pureconfig._
    getConfigType[YourCustomType](path, config)
    

    I hope this solves your problem