Open seigert opened 6 years ago
The problem is that com.typesafe.config.Config
is converted to io.circe.Json
without knowing what will be the final type of the "on"
string. As far as I know it is not possible to introspect the structure of the type when it is being decoded.
The only solution I can think of is to create a wrapper "boolean' type which allows to use an implicit convertion to translate from string to boolean as Typesafe config does.
import scala.language.implicitConversions
import org.scalatest.{ FlatSpec, Matchers }
import com.typesafe.config.ConfigFactory
import io.circe._
import io.circe.generic.auto._
import io.circe.config.syntax._
object ConfigBooleanSpec {
case class ConfigBoolean(value: Boolean)
object ConfigBoolean {
implicit def toBoolean(b: ConfigBoolean): Boolean = b.value
}
implicit val configBooleanDecoder: Decoder[ConfigBoolean] = {
val truthful = Set("true", "yes", "on")
Decoder.decodeString.map(s => ConfigBoolean(truthful(s)))
}
case class ServerConfig(host: String, port: Int, enabled: ConfigBoolean)
}
class ConfigBooleanSpec extends FlatSpec with Matchers {
import ConfigBooleanSpec._
"custom boolean" should "parse and decode from string" in {
val config = ConfigFactory.parseString(
"""
host = localhost
port = 8080
enabled = on
""")
val Right(ServerConfig(_, _, enabled)) = config.as[ServerConfig]
assert(enabled.value)
assert(enabled)
}
}
It would be good to document this though so if you are up for making a PR that would be great else let's keep this issue open until that gets fixed.
Sorry for the late answer, ConfigBoolean
is a possible solution, but it will not work with external/legacy entities with Boolean
attributes or providing their own Decoder
instance. Or if you just dont want to leak circe-config
details in your domain model.
I think better solution would be to delay conversion to Json
as much as possible or even do not convert at all, but it would require some kind of JsonDelegate
instance that does nothing but delegates fold(..)
and asNull|asBoolean|..
methods to it's underlying value. And I don't think it's possible with current circe
as Json
is sealed.
Maybe something could be done via ConfigCursor
version of HCursor
for Decoder
to use?
I agree that would be optimal but not sure it is possible to do this sort of lazy conversion.
It may be intended, but right now circe-config is inconsistent with original config for Boolean values written as strings:
It is possible to work around it, but it is not very convenient when passing config values via ENV_VARIABLES in K8s -- it disallows unquoted strings. :(