Skip to content
This repository was archived by the owner on Nov 30, 2025. It is now read-only.

Commit 2a83f2d

Browse files
authored
Merge pull request #247 from nefilim/main
Add quoted scalar and multi line Style configurable support
2 parents fb6522c + 8d9d527 commit 2a83f2d

3 files changed

Lines changed: 119 additions & 9 deletions

File tree

src/commonMain/kotlin/com/charleskorn/kaml/YamlConfiguration.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ public data class YamlConfiguration constructor(
4040
internal val polymorphismPropertyName: String = "type",
4141
internal val encodingIndentationSize: Int = 2,
4242
internal val breakScalarsAt: Int = 80,
43-
internal val sequenceStyle: SequenceStyle = SequenceStyle.Block
43+
internal val sequenceStyle: SequenceStyle = SequenceStyle.Block,
44+
internal val singleLineScalarStyle: SingleLineStringStyle = SingleLineStringStyle.DoubleQuoted,
45+
internal val multiLineStringStyle: MultiLineStringStyle = singleLineScalarStyle.multiLineStringStyle,
4446
)
4547

4648
public enum class PolymorphismStyle {
@@ -67,3 +69,20 @@ public enum class SequenceStyle {
6769
*/
6870
Flow
6971
}
72+
73+
public enum class MultiLineStringStyle {
74+
Literal,
75+
DoubleQuoted,
76+
SingleQuoted,
77+
}
78+
79+
public enum class SingleLineStringStyle {
80+
DoubleQuoted,
81+
SingleQuoted;
82+
83+
public val multiLineStringStyle: MultiLineStringStyle
84+
get() = when (this) {
85+
DoubleQuoted -> MultiLineStringStyle.DoubleQuoted
86+
SingleQuoted -> MultiLineStringStyle.SingleQuoted
87+
}
88+
}

src/jvmMain/kotlin/com/charleskorn/kaml/YamlOutput.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ internal class YamlOutput(
6666
override fun encodeNull() = emitPlainScalar("null")
6767
override fun encodeBoolean(value: Boolean) = emitPlainScalar(value.toString())
6868
override fun encodeByte(value: Byte) = emitPlainScalar(value.toString())
69-
override fun encodeChar(value: Char) = emitQuotedScalar(value.toString())
69+
override fun encodeChar(value: Char) = emitQuotedScalar(value.toString(), configuration.singleLineScalarStyle.scalarStyle)
7070
override fun encodeDouble(value: Double) = emitPlainScalar(value.toString())
7171
override fun encodeFloat(value: Float) = emitPlainScalar(value.toString())
7272
override fun encodeInt(value: Int) = emitPlainScalar(value.toString())
@@ -77,14 +77,17 @@ internal class YamlOutput(
7777
currentTypeName = value
7878
shouldReadTypeName = false
7979
} else {
80-
emitQuotedScalar(value)
80+
when {
81+
value.contains('\n') -> emitQuotedScalar(value, configuration.multiLineStringStyle.scalarStyle)
82+
else -> emitQuotedScalar(value, configuration.singleLineScalarStyle.scalarStyle)
83+
}
8184
}
8285
}
8386

84-
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = emitQuotedScalar(enumDescriptor.getElementName(index))
87+
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) = emitQuotedScalar(enumDescriptor.getElementName(index), configuration.singleLineScalarStyle.scalarStyle)
8588

8689
private fun emitPlainScalar(value: String) = emitScalar(value, ScalarStyle.PLAIN)
87-
private fun emitQuotedScalar(value: String) = emitScalar(value, ScalarStyle.DOUBLE_QUOTED)
90+
private fun emitQuotedScalar(value: String, scalarStyle: ScalarStyle) = emitScalar(value, scalarStyle)
8891

8992
override fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean {
9093
if (descriptor.kind is StructureKind.CLASS) {
@@ -111,7 +114,7 @@ internal class YamlOutput(
111114

112115
if (typeName.isPresent) {
113116
emitPlainScalar(configuration.polymorphismPropertyName)
114-
emitQuotedScalar(typeName.get())
117+
emitQuotedScalar(typeName.get(), SingleLineStringStyle.DoubleQuoted.scalarStyle)
115118
}
116119
}
117120
}
@@ -162,6 +165,19 @@ internal class YamlOutput(
162165
SequenceStyle.Flow -> FlowStyle.FLOW
163166
}
164167

168+
private val MultiLineStringStyle.scalarStyle: ScalarStyle
169+
get() = when (this) {
170+
MultiLineStringStyle.DoubleQuoted -> ScalarStyle.DOUBLE_QUOTED
171+
MultiLineStringStyle.SingleQuoted -> ScalarStyle.SINGLE_QUOTED
172+
MultiLineStringStyle.Literal -> ScalarStyle.LITERAL
173+
}
174+
175+
private val SingleLineStringStyle.scalarStyle: ScalarStyle
176+
get() = when (this) {
177+
SingleLineStringStyle.DoubleQuoted -> ScalarStyle.DOUBLE_QUOTED
178+
SingleLineStringStyle.SingleQuoted -> ScalarStyle.SINGLE_QUOTED
179+
}
180+
165181
companion object {
166182
private val ALL_IMPLICIT = ImplicitTuple(true, true)
167183
private val ALL_EXPLICIT = ImplicitTuple(false, false)

src/jvmTest/kotlin/com/charleskorn/kaml/JvmYamlWritingTest.kt

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,87 @@ import java.io.ByteArrayOutputStream
2828
object JvmYamlWritingTest : Spek({
2929
describe("JVM-specific extensions for YAML writing") {
3030
describe("writing to a stream") {
31-
val output = ByteArrayOutputStream()
32-
Yaml.default.encodeToStream(String.serializer(), "hello world", output)
33-
3431
it("returns the value serialized in the expected YAML form") {
32+
val output = ByteArrayOutputStream()
33+
Yaml.default.encodeToStream(String.serializer(), "hello world", output)
34+
3535
expect(output.toString(Charsets.UTF_8)).toEqual("\"hello world\"\n")
3636
}
37+
38+
it("should support block literal style output for multiline strings when configured") {
39+
with(
40+
Yaml(
41+
configuration = YamlConfiguration(
42+
multiLineStringStyle = MultiLineStringStyle.Literal,
43+
)
44+
)
45+
) {
46+
val output = ByteArrayOutputStream()
47+
encodeToStream(String.serializer(), "hello\nworld\nhow are | you?\n", output)
48+
49+
expect(output.toString(Charsets.UTF_8)).toEqual(
50+
"""
51+
|
52+
hello
53+
world
54+
how are | you?
55+
56+
""".trimIndent()
57+
)
58+
}
59+
60+
with(
61+
Yaml(
62+
configuration = YamlConfiguration(
63+
multiLineStringStyle = MultiLineStringStyle.DoubleQuoted,
64+
)
65+
)
66+
) {
67+
val output = ByteArrayOutputStream()
68+
encodeToStream(String.serializer(), "hello\nworld\nhow are | you?\n", output)
69+
expect(output.toString(Charsets.UTF_8)).toEqual(
70+
"""|"hello\nworld\nhow are | you?\n"
71+
|
72+
""".trimMargin()
73+
)
74+
}
75+
}
76+
77+
it("should support configurable scalar quoting") {
78+
with(
79+
Yaml(
80+
configuration = YamlConfiguration(
81+
singleLineScalarStyle = SingleLineStringStyle.SingleQuoted
82+
)
83+
)
84+
) {
85+
val output = ByteArrayOutputStream()
86+
encodeToStream(String.serializer(), "hello, world", output)
87+
88+
expect(output.toString(Charsets.UTF_8)).toEqual(
89+
"""|'hello, world'
90+
|
91+
""".trimMargin()
92+
)
93+
}
94+
95+
with(
96+
Yaml(
97+
configuration = YamlConfiguration(
98+
singleLineScalarStyle = SingleLineStringStyle.DoubleQuoted
99+
)
100+
)
101+
) {
102+
val output = ByteArrayOutputStream()
103+
encodeToStream(String.serializer(), "hello, world", output)
104+
105+
expect(output.toString(Charsets.UTF_8)).toEqual(
106+
"""|"hello, world"
107+
|
108+
""".trimMargin()
109+
)
110+
}
111+
}
37112
}
38113
}
39114
})

0 commit comments

Comments
 (0)