zio/zio-config

`.kebabCase` is not working for array in hocon config

bilal-fazlani opened this issue · 5 comments

object TestApp2 extends zio.ZIOAppDefault:

  val config = """arr = ["a", "b", "c"]"""

  case class CombinedArrayValue(arr: List[String])

  object CombinedArrayValue:
    val config: Config[CombinedArrayValue] = deriveConfig[CombinedArrayValue]

  override val bootstrap: ZLayer[Any, Nothing, Unit] =
    Runtime.setConfigProvider(
      TypesafeConfigProvider
          .fromHoconString(config)
          .kebabCase  // <-- problem
    )

  def run = ZIO
    .config(CombinedArrayValue.config)
    .debug("result")
    .exitCode

Output:

<FAIL> result: Fail((Missing data at arr: Expected arr to be set in properties),Stack trace for thread "zio-fiber-4":
        at example.TestApp2.run(TestApp.scala:114)
        at example.TestApp2.run(TestApp.scala:115)
        at example.TestApp2.run(TestApp.scala:116))

If I remove the .kebabCase call, it works.

Output after removing .kebabCase

result: CombinedArrayValue(List(a, b, c))

zioConfigVersion = "4.0.0-RC10"

@bilal-fazlani I will take a look. There are some ongoing work back in ZIO to handle a few cases.

Thanks!

.kebabCase in RC version falls back to ZIO core's Flat and Flat which really couldn't represent the array structure in the above format.

To unblock yourself during the RC versions, you can use the standard methods in zio-config such as mapKey

import zio.config._

CombinedArrayValue.config.mapKey(toKebabCase)) // and avoid .kebabCase in the provider

Solution to this inconsistency is on it's way!

With zio/zio#7823 (merged earlier, but we couldn't use it yet) and zio/zio#7891 (merged recently), zio-config can now depend on latest ZIO to allow your original code to work

@afsalthaj is this available in a published zio and zio-config version?

The below is failing for me with error

zio.Config$Error$MissingData: (Missing data at settings.an-array: 
Expected settingsan-array to be set in properties)
case class Settings(
    anArray: List[String]
)
object Settings {
  val config: Config[Settings] =
    (deriveConfig[Settings]).nested("settings")
}

object TestMain extends ZIOAppDefault {

  override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
    Runtime.setConfigProvider(configProvider)

  lazy val configProvider = TypesafeConfigProvider
    .fromHoconString(s"""
  |settings={
  |  an-array = ["a", "b", "c"] 
  |}
  """.stripMargin)
    .kebabCase

  def run = for {
    c <- ZIO.config(Settings.config)
    _ <- Console.printLine(c.toString)
  } yield ()
}

I am using

val zioVersion       = "2.0.10"
val zioConfigVersion = "4.0.0-RC14"