Deep dive into PureConfig types in Scala


Folks, I am back with some more exploration on PureConfig. This time we will talk about the types. For types, we have following two things to discuss:

  • New supported types
  • Override behaviour for types
  • In this blog, we will discuss only the first one i.e. New supported types

    New supported types: PureConfig does not support all kind of types. For ex, classes that are not case classes are not supported out-of-the-box

    import pureconfig.error.ConfigReaderFailures
    import pureconfig.{ConfigReader, loadConfig}
    import pureconfig.ConvertHelpers._
    
    case class Company1(company: CompanyDetails1)
    
    class Year(value: Int){
      override def toString: String = s"Year($value)"
    }
    
    case class CompanyDetails1(fullName: String,
                              started: Year,
                              employees: String,
                              offices: List[String],
                              officesInIndia: Map[String, String],
                              extraActivity: Option[String])
    

    In order to read an instance of a given type T from a config, PureConfig needs to have in scope in implicit instance of ConfigReader[T] for that type.

    You can see above that Year is not a case class. Therefore, this won’t compile because there’s no ConfigReader instance for Year:

    // load config
    def getConfig: Either[ConfigReaderFailures, Company1]  = loadConfig[Company1]
    
    //errors
    Error:(11, 70) could not find implicit value for parameter reader: pureconfig.ConfigReader[com.knoldus.conf.Company1]
      def getConfig: Either[ConfigReaderFailures, Company1]  = loadConfig[Company1]
    
    Error:(11, 70) not enough arguments for method loadConfig: (implicit reader: pureconfig.ConfigReader[com.knoldus.conf.Company1])Either[pureconfig.error.ConfigReaderFailures,com.knoldus.conf.Company1].
    Unspecified value parameter reader.
      def getConfig: Either[ConfigReaderFailures, Company1]  = loadConfig[Company1]
    

    PureConfig can be extended to support those types. To do so, an instance for the ConfigReader type class must be provided.

    First, define a ConfigReader instance in implicit scope:

    import pureconfig.ConvertHelpers._
    
    class CustomType {
    
      implicit val myIntReader: ConfigReader[Year] = ConfigReader.fromString[Year](catchReadError(s => new Year(s.toInt)))
      def getConfig: Either[ConfigReaderFailures, Company1]  = loadConfig[Company1]
    
    }
    

    Now when we load the config, it will be loaded successfully :

    Company1(CompanyDetails1(Knoldus Software LLP,Year(2012),80-120,List(India, Singapore, US, Canada),Map(development -> Noida, head-office -> Delhi),None))
    
    

    You can check the list of supported types here. For more details on custom supported types, visit here.

    You can get the full code here.

    We will discuss the second point i.e. Override behaviour for types in next blog. Stay tuned for the same.

    I hope you will enjoy the reading and will have worth for you.

    Happy Blogging !!!

    Happy Coding !!!


    KNOLDUS-advt-sticker

    About Rishi Khandelwal

    Sr. Software Consultant having more than 6 years industry experience. He has working experience in various technologies such as Scala, Java, Play, Akka, Spark, Hive, Cassandra, Akka-http, ElasticSearch, Backbone.js, html5, javascript, Less, Amazon EC2, WebRTC, SBT
    This entry was posted in Scala. Bookmark the permalink.

    One Response to Deep dive into PureConfig types in Scala

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s