From 978cd7af3feb8ca652b6a0e11bb06ba10ba6a624 Mon Sep 17 00:00:00 2001 From: Seppe Volkaerts Date: Mon, 3 Feb 2020 18:44:48 +0100 Subject: [PATCH] Allow StdSerializers to output primitives and array structures. --- .../kotlin/com/uchuhimo/konf/source/Source.kt | 12 +-- .../serializer/PrimitiveStdSerializerSpec.kt | 89 +++++++++++++++++++ 2 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 konf-core/src/test/kotlin/com/uchuhimo/konf/source/serializer/PrimitiveStdSerializerSpec.kt diff --git a/konf-core/src/main/kotlin/com/uchuhimo/konf/source/Source.kt b/konf-core/src/main/kotlin/com/uchuhimo/konf/source/Source.kt index 87c4b716..5c09b1f8 100644 --- a/konf-core/src/main/kotlin/com/uchuhimo/konf/source/Source.kt +++ b/konf-core/src/main/kotlin/com/uchuhimo/konf/source/Source.kt @@ -476,10 +476,9 @@ internal fun Any?.toCompatibleValue(mapper: ObjectMapper): Any { is LongArray -> this.toList() is DoubleArray -> this.toList() is FloatArray -> this.toList() - is List<*> -> this.map { it!!.toCompatibleValue(mapper) } - is Set<*> -> this.map { it!!.toCompatibleValue(mapper) } - is Array<*> -> this.map { it!!.toCompatibleValue(mapper) } - is Map<*, *> -> this.mapValues { (_, value) -> value!!.toCompatibleValue(mapper) } + is Iterable<*> -> this.map { it.toCompatibleValue(mapper) } + is Array<*> -> this.map { it.toCompatibleValue(mapper) } + is Map<*, *> -> this.mapValues { (_, value) -> value.toCompatibleValue(mapper) } is Char -> this.toString() is String, is Boolean, @@ -495,10 +494,7 @@ internal fun Any?.toCompatibleValue(mapper: ObjectMapper): Any { if (this == null) { "null" } else { - val result = mapper.convertValue(this, Map::class.java).mapValues { (_, value) -> - value.toCompatibleValue(mapper) - } - result + mapper.convertValue(this, Any::class.java).toCompatibleValue(mapper) } } } diff --git a/konf-core/src/test/kotlin/com/uchuhimo/konf/source/serializer/PrimitiveStdSerializerSpec.kt b/konf-core/src/test/kotlin/com/uchuhimo/konf/source/serializer/PrimitiveStdSerializerSpec.kt new file mode 100644 index 00000000..d1f36891 --- /dev/null +++ b/konf-core/src/test/kotlin/com/uchuhimo/konf/source/serializer/PrimitiveStdSerializerSpec.kt @@ -0,0 +1,89 @@ +/* + * Copyright 2017-2019 the original author or authors. + * + * 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.uchuhimo.konf.source.serializer + +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import com.uchuhimo.konf.Config +import com.uchuhimo.konf.ConfigSpec +import com.uchuhimo.konf.source.json.toJson +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.given +import org.jetbrains.spek.api.dsl.on +import org.junit.jupiter.api.assertDoesNotThrow +import java.io.StringReader +import java.io.StringWriter +import kotlin.test.assertEquals + +object PrimitiveStdSerializerSpec : Spek({ + val config = Config { + addSpec(WrappedStringSpec) + mapper.registerModule(SimpleModule().apply { + addSerializer(WrappedString::class.java, WrappedStringStdSerializer()) + addDeserializer(WrappedString::class.java, WrappedStringStdDeserializer()) + }) + } + + given("a config") { + on("write json") { + val writer = StringWriter() + assertDoesNotThrow { + config.toJson.toWriter(writer) + } + assert(writer.toString().contains("\"wrapped-string\" : \"value\"")) + } + + val json = """ + { + "wrapped-string" : "1234" + } + """.trimIndent() + given("json") { + on("read json") { + val read = config.from.json.reader(StringReader(json)) + assertEquals(WrappedString("1234"), read[WrappedStringSpec.wrappedString]) + } + } + } + +}) + +private object WrappedStringSpec : ConfigSpec("") { + + val wrappedString by optional(name = "wrapped-string", default = WrappedString("value")) +} + +private class WrappedStringStdSerializer : StdSerializer(WrappedString::class.java) { + + override fun serialize(value: WrappedString, gen: JsonGenerator, provider: SerializerProvider) { + gen.writeString(value.string) + } +} + +private class WrappedStringStdDeserializer : StdDeserializer(WrappedString::class.java) { + + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): WrappedString { + return WrappedString(p.valueAsString) + } +} + +private data class WrappedString(val string: String)