Overriding Behavior for Types

It is possible to override the behavior of PureConfig for a given type T just by putting another implicit instance of ConfigReader[T] in scope. This happens because the newly defined implicit value will have a higher priority than the ones defined by PureConfig, according to the Scala implicit precedence rules.

For instance, the default behavior of PureConfig for String is to return the string itself in the configuration:

import com.typesafe.config.ConfigValueFactory
import pureconfig._
import pureconfig.generic.auto._
ConfigReader[String].from(ConfigValueFactory.fromAnyRef("FooBar"))
// res0: Either[pureconfig.error.ConfigReaderFailures,String] = Right(FooBar)

Now let’s say that we want to override this behavior such that Strings are always read lower case. We can define a custom ConfigReader instance for String:

import pureconfig.ConvertHelpers._

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

PureConfig will now use the custom overrideStrReader instance:

ConfigReader[String].from(ConfigValueFactory.fromAnyRef("FooBar"))
// res1: Either[pureconfig.error.ConfigReaderFailures,String] = Right(foobar)

All the techniques described in Supporting New Types can be used to define the higher priority reader.

PureConfig has more fine-grained ways to configure the default readers for case classes and sealed families. The Case Classes and Sealed Families subsections show how to do that.