Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Overriding PureConfig Behavior in Scala

DZone's Guide to

Overriding PureConfig Behavior in Scala

PureConfig allows devs more control over configuring Scala output. Learn how to use it to tweak your reading and writing capabilities.

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

PureConfig has its own predefined behavior for reading and writing to configuration files, but sometimes we get a tricky requirement where we need some specific behavior; for example, to read the config.

It is possible to override the behavior of PureConfig for a certain type by implementing another instance of ConfigReader, ConfigWriter, or ConfigConvert. So in this blog, we will discuss all three override types.

ConfigReader

The default behavior of PureConfig for Strings is to return the String itself in the configuration.
For example, when the configuration below is read by PureConfig, it will be read as it is:

application.conf:

company {
    full-name = "Knoldus Software LLP"
    started = 2012
    employees = "80-120"
    offices = ["India", "Singapore", "US", "Canada"]
    offices-in-india {
        head-office = "Delhi"
        development = "Noida"
    }
}


Reading configuration:

import pureconfig.error.ConfigReaderFailures
import pureconfig.loadConfig
 
class SimpleConfig {
    def getConfig: Either[ConfigReaderFailures, Company] = loadConfig[Company]
}
 
case class Company(company: CompanyDetails)
 
case class CompanyDetails(fullName: String,
                          started: Int,
                          employees: String,
                          offices: List[String],
                          officesInIndia: Map[String, String],
                          extraActivity: Option[String])
 
 
// Calling and displaying the configuration
val simpleConfig = new SimpleConfig().getConfig
 
    simpleConfig match {
        case Left(ex) => ex.toList.foreach(println)
 
      case Right(config) => 
          println(s"Company's Name ${config.company.fullName}")
          println(s"Company started at ${config.company.started}")
          println(s"Company's strength is ${config.company.employees}")
          println(s"Company's presence are in  ${config.company.offices}")
          println(s"Company's office in India are  ${config.company.officesInIndia}")
          println(s"Company's extra activity is  ${config.company.extraActivity}")
    }


Output:

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


This is the default behavior of ConfigReader, in which the output is same as it is defined in configuration file.

Now let’s try to override the above behavior. Now say we want it so that Strings are always read in upper case. For this, we need to define a custom ConfigReader instance for String:

implicit val overrideStrReader = ConfigReader.fromString[String](catchReadError(_.toUpperCase()))


After adding the above line, let's take a look at the output:

KNOLDUS SOFTWARE LLP
2012
80-120
List(INDIA, SINGAPORE, US, CANADA)
Map(development -> NOIDA, head-office -> DELHI)


View the full code on GitHub.

ConfigWriter

Add the line below to override the String write behavior:

implicit val myStringWriter = ConfigWriter.toString[String](n => s"$n !!!")


Write config:

val companyDetails = CompanyDetails("Knoldus Software LLP", 2012, "80-120", Nil, Map(), None)
    val conf = Company(companyDetails).toConfig
println(conf)


Output:

SimpleConfigObject(
    {
        "company":
            {
                "employees":"80-120 !!!","full-name":"Knoldus Software LLP !!!","offices":
                    [
                    ],
                "offices-in-india":{
                }
                ,"started":2012
            }
    }
)


You can see above that “!!!” has been appended to the each string value.

View the full code on GitHub

ConfigConvert

If you want to define both operations, the easier way to add full support for a class is by creating a ConfigConvert:

implicit val myStringConvert = ConfigConvert.viaString[String](
    catchReadError(s => s.toUpperCase ), n => s"$n !!!")


A ConfigConvert is both an instance of ConfigReader and an instance of ConfigWriter, so it can be used anywhere one of them is required.

View full code on GitHub

That’s it! Hope you enjoy the reading.

Happy coding!

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.

Topics:
java ,scala ,pureconfig ,configuration ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}