Skip to content

Instantly share code, notes, and snippets.

@kastoestoramadus
Last active September 25, 2025 14:51
Show Gist options
  • Save kastoestoramadus/407bd8eecd33325e5143993a7230d6b7 to your computer and use it in GitHub Desktop.
Save kastoestoramadus/407bd8eecd33325e5143993a7230d6b7 to your computer and use it in GitHub Desktop.
scala script
// bugfix for simplify single entry object rendering
// if you want to understand then compare treating object in corner cases: atRoot and inside an array
if(v.isInstanceOf[SimpleConfigObject]) {
val redact = new jl.StringBuilder()
v.renderValue(redact, indentVal + 1, atRoot, options)
if(options.getConfigFormatOptions.getSimplifyNestedObjects &&
redact.charAt(redact.length() - 1) != '}'
) {
redact.insert(0, "{ ")
redact.append(" }")
} // else no bonus chars added
sb.append(redact.toString)
} else
v.renderValue(sb, indentVal + 1, atRoot, options)
private def trySimplifyTheOnlyNestedObjectRec(
keysAggregate: String
): Option[(String, AbstractConfigValue)] =
if (value.size() == 1) {
val newKeyElement = ConfigImplUtil.renderStringUnquotedIfPossible(
keySet.iterator().next()
)
val newAggregate = (if (keysAggregate.isEmpty) ""
else s"$keysAggregate.") + newKeyElement
values.iterator().next() match {
case other: AbstractConfigValue =>
Some(newAggregate -> other)
case _ => None
}
} else None
private def trySimplifyTheOnlyNestedObject(
options: ConfigRenderOptions
): Option[(String, AbstractConfigValue)] =
if (!(options.getFormatted && options.getConfigFormatOptions.getSimplifyNestedObjects) || options.getJson) {
None
} else trySimplifyTheOnlyNestedObjectRec("")
override def renderValue(
sb: jl.StringBuilder,
indentVal: Int,
atRoot: Boolean,
options: ConfigRenderOptions
): Unit = {
if (isEmpty) sb.append("{}")
else {
trySimplifyTheOnlyNestedObject(options) match {
case Some((aggKey, leafValue)) =>
if (!atRoot) { // nasty glue
// first render of an object at key was done in outer scope
val lastCharIdx = sb.length() - 1
if (options.getFormatted && lastCharIdx > 0 && sb.charAt(lastCharIdx) == ' ')
sb.deleteCharAt(lastCharIdx)
if(sb.length() > 0 && !ConfigImplUtil.isForbiddenUnquotedChar(
sb.charAt(sb.length() - 1) // should extend path only on identifier
)) sb.append('.')
}
val redact = new jl.StringBuilder()
leafValue match {
case innerSCO: SimpleConfigObject if innerSCO.trySimplifyTheOnlyNestedObjectRec(aggKey).isDefined =>
leafValue.renderWithRenderedKey(redact, s"$aggKey.", options)
// remove space from regular formatting
redact.deleteCharAt(redact.length() - 1)
leafValue.renderValue(redact, indentVal, false, options)
case _ => // last leaf
leafValue.renderWithRenderedKey(redact, s"$aggKey", options)
leafValue.renderValue(redact, indentVal, false, options)
}
sb.append(redact.toString())
case _ =>
renderValueAsMultiLineObject(sb, indentVal, atRoot, options)
}
}
if (atRoot && options.getFormatted && options.getConfigFormatOptions.getNewLineAtEnd)
sb.append('\n')
}
@Test
def simplifyOneEntryNestedObjectsArray(): Unit = {
implicit val configFormatOptions =
defaultFormatOptions.setSimplifyNestedObjects(true)
val in =
"""r { ma: [ { si.foo: so } ]
| kio: 1
| }""".stripMargin
val result = formatHocon(in)
val expected =
"""r {
| kio = 1
| ma = [
| { si.foo = so }
| ]
|}
|""".stripMargin
println(result)
println(expected)
checkEqualObjects(expected, result)
}
@Test
def simplifyOneEntryNestedObjectsNotOnRoot(): Unit = {
implicit val configFormatOptions =
defaultFormatOptions.setSimplifyNestedObjects(true)
val in =
"""r { p { "d.ap" { s= 42 } }
| e.h {
| f= 1
| foo.bar= 2
| }}
| g.d {s=44}""".stripMargin
val result = formatHocon(in)
val expected =
"""g.d.s = 44
|r {
| e.h {
| f = 1
| foo.bar = 2
| }
| p."d.ap".s = 42
|}
|""".stripMargin
checkEqualObjects(expected, result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment