Skip to content

Commit

Permalink
Merge pull request #287 from slava110/comments
Browse files Browse the repository at this point in the history
Added experimental comment support on serialization
  • Loading branch information
charleskorn authored Jun 5, 2022
2 parents ed6c19f + 9094050 commit 1b26562
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/commonMain/kotlin/com/charleskorn/kaml/YamlComment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright 2018-2021 Charles Korn.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package com.charleskorn.kaml

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Adds a comment block before property on serialization
* @property lines comment lines to add
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.BINARY)
@SerialInfo
public annotation class YamlComment(
vararg val lines: String
)
29 changes: 29 additions & 0 deletions src/commonTest/kotlin/com/charleskorn/kaml/YamlWritingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,23 @@ class YamlWritingTest : DescribeSpec({
}
}
}

describe("handling comments") {
context("comments in kotlin object") {
val input = SimpleStructureWithComments("objName", 73, "justTest")

it("is written") {
Yaml.default.encodeToString(SimpleStructureWithComments.serializer(), input) shouldBe """
name: "objName"
# Cool int
myInt: 73
# Testing
# multiline
test: "justTest"
""".trimIndent()
}
}
}
}
})

Expand All @@ -898,5 +915,17 @@ private data class SimpleStructureWithDefault(
val name: String = "default"
)

@Serializable
private data class SimpleStructureWithComments(
val name: String,
@YamlComment("Cool int")
val myInt: Int,
@YamlComment(
"Testing",
"multiline"
)
val test: String
)

@Serializable
private data class ThingWithMap(val variables: Map<String, String>)
18 changes: 18 additions & 0 deletions src/jvmMain/kotlin/com/charleskorn/kaml/YamlOutput.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ import kotlinx.serialization.encoding.CompositeEncoder
import kotlinx.serialization.modules.SerializersModule
import org.snakeyaml.engine.v2.api.DumpSettings
import org.snakeyaml.engine.v2.api.StreamDataWriter
import org.snakeyaml.engine.v2.comments.CommentType
import org.snakeyaml.engine.v2.common.FlowStyle
import org.snakeyaml.engine.v2.common.ScalarStyle
import org.snakeyaml.engine.v2.emitter.Emitter
import org.snakeyaml.engine.v2.events.CommentEvent
import org.snakeyaml.engine.v2.events.DocumentEndEvent
import org.snakeyaml.engine.v2.events.DocumentStartEvent
import org.snakeyaml.engine.v2.events.ImplicitTuple
Expand Down Expand Up @@ -90,6 +92,8 @@ internal class YamlOutput(
private fun emitQuotedScalar(value: String, scalarStyle: ScalarStyle) = emitScalar(value, scalarStyle)

override fun encodeElement(descriptor: SerialDescriptor, index: Int): Boolean {
encodeComment(descriptor, index)

if (descriptor.kind is StructureKind.CLASS) {
emitPlainScalar(descriptor.getElementName(index))
}
Expand Down Expand Up @@ -142,6 +146,20 @@ internal class YamlOutput(
emitter.emit(StreamEndEvent())
}

private fun encodeComment(descriptor: SerialDescriptor, index: Int) {
val commentAnno = descriptor.getElementAnnotations(index)
.filterIsInstance<YamlComment>()
.firstOrNull()

if (commentAnno == null) {
return
}

for (line in commentAnno.lines) {
emitter.emit(CommentEvent(CommentType.BLOCK, " $line", Optional.empty(), Optional.empty()))
}
}

private fun emitScalar(value: String, style: ScalarStyle) {
val tag = getAndClearTypeName()

Expand Down

0 comments on commit 1b26562

Please sign in to comment.