Every ConfigSource at the core is just a Reader
,
which is essentially a function that goes from PropertyTreePath
to an actual PropertyTree
.
Every ConfigSource at the core is just a Reader
,
which is essentially a function that goes from PropertyTreePath
to an actual PropertyTree
.
i.e, f: PropertyTreePath[String] => IO[ReadError[String], PropertyTree[String, String]
Later on for each key
represented as PropertyTreePath[String]
internally, f
is used to
applied to get the value as a PropertyTree
itself.
Internal details:
This function f
can be retrieved under an ZManaged effect. This implies it may involve an IO with managing resources
to even form this function. Example: In order to retrieve a property-tree corresponding to a key (PropertyTreePath),
it requires a database connection in the very first instance.
// pseudo-logic, doesn't compile
val source: ConfigSource = ConfigSource.Reader( ZManaged(getDatabaseConnection) .flatMap(connection => (key: PropertyTreePath[String] => IO.effect(connection.getStatement.executeQuery(s"get key from table"))) )
Note that ConfigSource
has a generalised memoize
function that allows you to memoize the effect required to form the
function. In the context of the above example, with source.memoize
we acquire only a single connection to retrieve
the values for all the keys in your product/coproduct for an instance of read
.