Skip to content

Commit c041c2c

Browse files
authored
Change default value of encodeDefaults config flag (#1084)
Motivated by the fact that this behavior is what users usually want from framework; GSON and Moshi already do that. * Switch `encodeDefaults` flag in default JsonConfiguration to false. * Flip encodeDefaults flag for Protobuf & Cbor * Bring back accidentally lost tests after runtime->core moving
1 parent 47ebf82 commit c041c2c

File tree

28 files changed

+127
-97
lines changed

28 files changed

+127
-97
lines changed

docs/basic-serialization.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ This chapter shows the basic use of Kotlin Serialization and explains its core c
2020
* [Optional property initializer call](#optional-property-initializer-call)
2121
* [Required properties](#required-properties)
2222
* [Transient properties](#transient-properties)
23-
* [Defaults are encoded](#defaults-are-encoded)
23+
* [Defaults are not encoded](#defaults-are-not-encoded)
2424
* [Nullable properties](#nullable-properties)
2525
* [Type safety is enforced](#type-safety-is-enforced)
2626
* [Referenced objects](#referenced-objects)
@@ -421,9 +421,10 @@ Use 'ignoreUnknownKeys = true' in 'Json {}' builder to ignore unknown keys.
421421

422422
> 'ignoreUnknownKeys' feature is explained in the [Ignoring Unknown Keys section](json.md#ignoring-unknown-keys) section.
423423
424-
### Defaults are encoded
424+
### Defaults are not encoded
425425

426-
Default values are still encoded by default.
426+
Default values are not encoded by default in JSON. This behavior is motivated by the fact that in most real-life scenarios,
427+
such configuration reduces visual clutter and saves amount of data being serialized.
427428

428429
```kotlin
429430
@Serializable
@@ -437,10 +438,10 @@ fun main() {
437438

438439
> You can get the full code [here](../guide/example/example-classes-09.kt).
439440
440-
It produces the following output, which has `language` property, even though its value is equal to the default one.
441+
It produces the following output, which does not have `language` property, because its value is equal to the default one.
441442

442443
```text
443-
{"name":"kotlinx.serialization","language":"Kotlin"}
444+
{"name":"kotlinx.serialization"}
444445
```
445446

446447
> See [Encoding defaults](json.md#encoding-defaults) section on how this behavior can be configured for JSON.
@@ -463,10 +464,10 @@ fun main() {
463464

464465
> You can get the full code [here](../guide/example/example-classes-10.kt).
465466
466-
This example explicitly encodes `null` in JSON because [Defaults are encoded](#defaults-are-encoded).
467+
This example does not encode `null` in JSON because [Defaults are not encoded](#defaults-are-not-encoded).
467468

468469
```text
469-
{"name":"kotlinx.serialization","renamedTo":null}
470+
{"name":"kotlinx.serialization"}
470471
```
471472

472473
<!--- TEST -->

docs/polymorphism.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,9 @@ sealed class Project {
209209
class OwnedProject(override val name: String, val owner: String) : Project()
210210

211211
fun main() {
212+
val json = Json { encodeDefaults = true } // "status" will be skipped otherwise
212213
val data: Project = OwnedProject("kotlinx.coroutines", "kotlin")
213-
println(Json.encodeToString(data))
214+
println(json.encodeToString(data))
214215
}
215216
```
216217

docs/serialization-guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Once the project is set up, we can start serializing some classes.
2424
* <a name='optional-property-initializer-call'></a>[Optional property initializer call](basic-serialization.md#optional-property-initializer-call)
2525
* <a name='required-properties'></a>[Required properties](basic-serialization.md#required-properties)
2626
* <a name='transient-properties'></a>[Transient properties](basic-serialization.md#transient-properties)
27-
* <a name='defaults-are-encoded'></a>[Defaults are encoded](basic-serialization.md#defaults-are-encoded)
27+
* <a name='defaults-are-not-encoded'></a>[Defaults are not encoded](basic-serialization.md#defaults-are-not-encoded)
2828
* <a name='nullable-properties'></a>[Nullable properties](basic-serialization.md#nullable-properties)
2929
* <a name='type-safety-is-enforced'></a>[Type safety is enforced](basic-serialization.md#type-safety-is-enforced)
3030
* <a name='referenced-objects'></a>[Referenced objects](basic-serialization.md#referenced-objects)

formats/cbor/commonMain/src/kotlinx/serialization/cbor/Cbor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import kotlinx.serialization.modules.*
2525
* from corresponding Kotlin objects. However, other 3rd-party parsers (e.g. `jackson-dataformat-cbor`) may not accept such maps.
2626
*
2727
* @param encodeDefaults specifies whether default values of Kotlin properties are encoded.
28+
* False by default; meaning that properties with values equal to defaults will be elided.
2829
*/
2930
@ExperimentalSerializationApi
3031
public sealed class Cbor(
@@ -36,7 +37,7 @@ public sealed class Cbor(
3637
/**
3738
* The default instance of [Cbor]
3839
*/
39-
public companion object Default : Cbor(true, EmptySerializersModule, null)
40+
public companion object Default : Cbor(false, EmptySerializersModule, null)
4041

4142
override fun <T> encodeToByteArray(serializer: SerializationStrategy<T>, value: T): ByteArray {
4243
val output = ByteArrayOutput()

formats/cbor/jvmTest/src/kotlinx/serialization/cbor/TestUtilities.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package kotlinx.serialization.cbor
@@ -10,11 +10,12 @@ import com.fasterxml.jackson.module.kotlin.*
1010
import kotlinx.serialization.*
1111

1212
internal val cborJackson = ObjectMapper(CBORFactory()).apply { registerKotlinModule() }
13+
internal val defaultCbor = Cbor { encodeDefaults = true }
1314

1415
internal inline fun <reified T : Any> dumpCborCompare(it: T, alwaysPrint: Boolean = false): Boolean {
1516
var parsed: T?
1617
val c = try {
17-
val bytes = Cbor.encodeToByteArray(it)
18+
val bytes = defaultCbor.encodeToByteArray(it)
1819
parsed = cborJackson.readValue<T>(bytes)
1920
it == parsed
2021
} catch (e: Exception) {
@@ -30,7 +31,7 @@ internal inline fun <reified T: Any> readCborCompare(it: T, alwaysPrint: Boolean
3031
var obj: T?
3132
val c = try {
3233
val hex = cborJackson.writeValueAsBytes(it)
33-
obj = Cbor.decodeFromByteArray(hex)
34+
obj = defaultCbor.decodeFromByteArray(hex)
3435
obj == it
3536
} catch (e: Exception) {
3637
obj = null

formats/json/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ kotlin {
1919
jvmTest {
2020
dependencies {
2121
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
22+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
2223
}
2324
}
2425
}

formats/json/commonMain/src/kotlinx/serialization/json/JsonConfiguration.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import kotlin.jvm.*
1515
"'Json(MyJsonConfiguration.copy(prettyPrint = true))' can be replaced with 'Json(from = MyApplicationJson) { prettyPrint = true }'"
1616
)
1717
public open class JsonConfiguration(
18-
internal val encodeDefaults: Boolean = true,
18+
internal val encodeDefaults: Boolean = false,
1919
internal val ignoreUnknownKeys: Boolean = false,
2020
internal val isLenient: Boolean = false,
2121
internal val serializeSpecialFloatingPointValues: Boolean = false,

formats/json/commonMain/src/kotlinx/serialization/json/internal/JsonConf.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import kotlin.jvm.*
1111
// Mirror of the deprecated JsonConfiguration. Not for external use.
1212
@OptIn(ExperimentalSerializationApi::class)
1313
internal data class JsonConf(
14-
@JvmField public val encodeDefaults: Boolean = true,
14+
@JvmField public val encodeDefaults: Boolean = false,
1515
@JvmField public val ignoreUnknownKeys: Boolean = false,
1616
@JvmField public val isLenient: Boolean = false,
1717
@JvmField public val allowStructuredMapKeys: Boolean = false,

formats/json/commonTest/src/kotlinx/serialization/SerializerForNullableTypeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public class SerializerForNullableTypeTest : JsonTestBase() {
8585

8686
@Serializable
8787
data class NullablePrimitive(
88-
@Serializable(with = NullableLongSerializer::class) val value: Long? = null
88+
@Serializable(with = NullableLongSerializer::class) val value: Long?
8989
)
9090

9191
@Test

formats/json/commonTest/src/kotlinx/serialization/features/ContextAndPolymorphicTest.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@ package kotlinx.serialization.features
77
import kotlinx.serialization.*
88
import kotlinx.serialization.builtins.*
99
import kotlinx.serialization.descriptors.*
10-
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
1110
import kotlinx.serialization.encoding.*
12-
import kotlinx.serialization.internal.*
1311
import kotlinx.serialization.json.*
1412
import kotlinx.serialization.modules.*
15-
import kotlinx.serialization.test.InternalHexConverter
13+
import kotlinx.serialization.test.*
1614
import kotlin.test.*
1715

1816
class ContextAndPolymorphicTest {
@@ -58,6 +56,7 @@ class ContextAndPolymorphicTest {
5856
val bPolymorphicModule = SerializersModule { polymorphic(Any::class) { subclass(PayloadSerializer) } }
5957
json = Json {
6058
useArrayPolymorphism = true
59+
encodeDefaults = true
6160
serializersModule = scope + bPolymorphicModule
6261
}
6362
}
@@ -131,7 +130,7 @@ class ContextAndPolymorphicTest {
131130

132131
@Test
133132
fun testContextualSerializerUsesDefaultIfModuleIsEmpty() {
134-
val s = Json { useArrayPolymorphism = true }.encodeToString(EnhancedData.serializer(), value)
133+
val s = Json { useArrayPolymorphism = true; encodeDefaults = true }.encodeToString(EnhancedData.serializer(), value)
135134
assertEquals("""{"data":{"a":100500,"b":42},"stringPayload":{"s":"string"},"binaryPayload":"62696E617279"}""", s)
136135
}
137136
}

0 commit comments

Comments
 (0)