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

Make it happen: rapid app development on Kubernetes as a managed service.

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!

Tutorial: WordPress as distributed microservices on Kubernetes.

Topics:
java ,scala ,pureconfig ,configuration ,tutorial

Published at DZone with permission of Rishi Khandelwal, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}