Skip to content

Commit bb67a8c

Browse files
committed
Recommend using fully qualified name in examples with SerialDescriptor creation
because serial names should be unique across all dependencies. Fixes #2247 and #2799 (comment)
1 parent a024572 commit bb67a8c

16 files changed

+42
-34
lines changed

docs/serializers.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ import kotlinx.serialization.descriptors.*
247247

248248
```kotlin
249249
object ColorAsStringSerializer : KSerializer<Color> {
250-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
250+
// Serial names of descriptors should be unique, this is why we advise including app package in the name.
251+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
251252

252253
override fun serialize(encoder: Encoder, value: Color) {
253254
val string = value.rgb.toString(16).padStart(6, '0')
@@ -315,7 +316,7 @@ Deserialization is also straightforward because we implemented the `deserialize`
315316

316317
<!--- INCLUDE
317318
object ColorAsStringSerializer : KSerializer<Color> {
318-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
319+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
319320
320321
override fun serialize(encoder: Encoder, value: Color) {
321322
val string = value.rgb.toString(16).padStart(6, '0')
@@ -349,7 +350,7 @@ It also works if we serialize or deserialize a different class with `Color` prop
349350

350351
<!--- INCLUDE
351352
object ColorAsStringSerializer : KSerializer<Color> {
352-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
353+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
353354
354355
override fun serialize(encoder: Encoder, value: Color) {
355356
val string = value.rgb.toString(16).padStart(6, '0')
@@ -404,8 +405,9 @@ import kotlinx.serialization.builtins.IntArraySerializer
404405

405406
class ColorIntArraySerializer : KSerializer<Color> {
406407
private val delegateSerializer = IntArraySerializer()
407-
@OptIn(ExperimentalSerializationApi::class)
408-
override val descriptor = SerialDescriptor("Color", delegateSerializer.descriptor)
408+
409+
// Serial names of descriptors should be unique, this is why we advise including app package in the name.
410+
override val descriptor = SerialDescriptor("my.app.Color", delegateSerializer.descriptor)
409411

410412
override fun serialize(encoder: Encoder, value: Color) {
411413
val data = intArrayOf(
@@ -487,7 +489,8 @@ generated [SerialDescriptor] for the surrogate because it should be indistinguis
487489

488490
```kotlin
489491
object ColorSerializer : KSerializer<Color> {
490-
override val descriptor: SerialDescriptor = ColorSurrogate.serializer().descriptor
492+
// Serial names of descriptors should be unique, so we cannot use ColorSurrogate.serializer().descriptor directly
493+
override val descriptor: SerialDescriptor = SerialDescriptor("my.app.Color", ColorSurrogate.serializer().descriptor)
491494

492495
override fun serialize(encoder: Encoder, value: Color) {
493496
val surrogate = ColorSurrogate((value.rgb shr 16) and 0xff, (value.rgb shr 8) and 0xff, value.rgb and 0xff)
@@ -542,7 +545,7 @@ for the corresponding fields by their type. The order of elements is important.
542545
543546
```kotlin
544547
override val descriptor: SerialDescriptor =
545-
buildClassSerialDescriptor("Color") {
548+
buildClassSerialDescriptor("my.app.Color") {
546549
element<Int>("r")
547550
element<Int>("g")
548551
element<Int>("b")
@@ -633,7 +636,7 @@ The plugin-generated serializers are actually conceptually similar to the code b
633636
object ColorAsObjectSerializer : KSerializer<Color> {
634637
635638
override val descriptor: SerialDescriptor =
636-
buildClassSerialDescriptor("Color") {
639+
buildClassSerialDescriptor("my.app.Color") {
637640
element<Int>("r")
638641
element<Int>("g")
639642
element<Int>("b")
@@ -712,7 +715,8 @@ import java.text.SimpleDateFormat
712715
713716
```kotlin
714717
object DateAsLongSerializer : KSerializer<Date> {
715-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
718+
// Serial names of descriptors should be unique, so choose app-specific name in case some library also would declare a serializer for Date.
719+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
716720
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
717721
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
718722
}
@@ -757,7 +761,7 @@ import java.util.Date
757761
import java.text.SimpleDateFormat
758762

759763
object DateAsLongSerializer : KSerializer<Date> {
760-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
764+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
761765
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
762766
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
763767
}
@@ -798,7 +802,7 @@ import java.util.Date
798802
import java.text.SimpleDateFormat
799803

800804
object DateAsLongSerializer : KSerializer<Date> {
801-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
805+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
802806
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
803807
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
804808
}
@@ -842,7 +846,7 @@ import java.util.Date
842846
import java.text.SimpleDateFormat
843847

844848
object DateAsLongSerializer : KSerializer<Date> {
845-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
849+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
846850
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
847851
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
848852
}
@@ -882,13 +886,13 @@ import java.util.TimeZone
882886
import java.text.SimpleDateFormat
883887

884888
object DateAsLongSerializer : KSerializer<Date> {
885-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("DateAsLong", PrimitiveKind.LONG)
889+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
886890
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
887891
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
888892
}
889893

890894
object DateAsSimpleTextSerializer: KSerializer<Date> {
891-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("DateAsSimpleText", PrimitiveKind.LONG)
895+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsSimpleText", PrimitiveKind.LONG)
892896
private val format = SimpleDateFormat("yyyy-MM-dd").apply {
893897
// Here we explicitly set time zone to UTC so output for this sample remains locale-independent.
894898
// Depending on your needs, you may have to adjust or remove this line.
@@ -946,7 +950,7 @@ serialization, delegating everything to the underlying serializer of its `data`
946950
947951
```kotlin
948952
class BoxSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<Box<T>> {
949-
override val descriptor: SerialDescriptor = dataSerializer.descriptor
953+
override val descriptor: SerialDescriptor = SerialDescriptor("my.app.Box", dataSerializer.descriptor)
950954
override fun serialize(encoder: Encoder, value: Box<T>) = dataSerializer.serialize(encoder, value.contents)
951955
override fun deserialize(decoder: Decoder) = Box(dataSerializer.deserialize(decoder))
952956
}
@@ -1007,7 +1011,7 @@ An example of using two serializers at once:
10071011

10081012
<!--- INCLUDE
10091013
object ColorAsStringSerializer : KSerializer<Color> {
1010-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
1014+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
10111015

10121016
override fun serialize(encoder: Encoder, value: Color) {
10131017
val string = value.rgb.toString(16).padStart(6, '0')
@@ -1098,7 +1102,7 @@ import java.util.Date
10981102
import java.text.SimpleDateFormat
10991103
11001104
object DateAsLongSerializer : KSerializer<Date> {
1101-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
1105+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
11021106
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
11031107
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
11041108
}

guide/example/example-serializer-07.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import kotlinx.serialization.encoding.*
77
import kotlinx.serialization.descriptors.*
88

99
object ColorAsStringSerializer : KSerializer<Color> {
10-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
10+
// Serial names of descriptors should be unique, this is why we advise including app package in the name.
11+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
1112

1213
override fun serialize(encoder: Encoder, value: Color) {
1314
val string = value.rgb.toString(16).padStart(6, '0')

guide/example/example-serializer-08.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import kotlinx.serialization.encoding.*
77
import kotlinx.serialization.descriptors.*
88

99
object ColorAsStringSerializer : KSerializer<Color> {
10-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
10+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
1111

1212
override fun serialize(encoder: Encoder, value: Color) {
1313
val string = value.rgb.toString(16).padStart(6, '0')

guide/example/example-serializer-09.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import kotlinx.serialization.encoding.*
77
import kotlinx.serialization.descriptors.*
88

99
object ColorAsStringSerializer : KSerializer<Color> {
10-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
10+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
1111

1212
override fun serialize(encoder: Encoder, value: Color) {
1313
val string = value.rgb.toString(16).padStart(6, '0')

guide/example/example-serializer-10.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ import kotlinx.serialization.builtins.IntArraySerializer
1010

1111
class ColorIntArraySerializer : KSerializer<Color> {
1212
private val delegateSerializer = IntArraySerializer()
13-
@OptIn(ExperimentalSerializationApi::class)
14-
override val descriptor = SerialDescriptor("Color", delegateSerializer.descriptor)
13+
14+
// Serial names of descriptors should be unique, this is why we advise including app package in the name.
15+
override val descriptor = SerialDescriptor("my.app.Color", delegateSerializer.descriptor)
1516

1617
override fun serialize(encoder: Encoder, value: Color) {
1718
val data = intArrayOf(

guide/example/example-serializer-11.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ private class ColorSurrogate(val r: Int, val g: Int, val b: Int) {
1515
}
1616

1717
object ColorSerializer : KSerializer<Color> {
18-
override val descriptor: SerialDescriptor = ColorSurrogate.serializer().descriptor
18+
// Serial names of descriptors should be unique, so we cannot use ColorSurrogate.serializer().descriptor directly
19+
override val descriptor: SerialDescriptor = SerialDescriptor("my.app.Color", ColorSurrogate.serializer().descriptor)
1920

2021
override fun serialize(encoder: Encoder, value: Color) {
2122
val surrogate = ColorSurrogate((value.rgb shr 16) and 0xff, (value.rgb shr 8) and 0xff, value.rgb and 0xff)

guide/example/example-serializer-12.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.*
99
object ColorAsObjectSerializer : KSerializer<Color> {
1010

1111
override val descriptor: SerialDescriptor =
12-
buildClassSerialDescriptor("Color") {
12+
buildClassSerialDescriptor("my.app.Color") {
1313
element<Int>("r")
1414
element<Int>("g")
1515
element<Int>("b")

guide/example/example-serializer-13.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.*
99
object ColorAsObjectSerializer : KSerializer<Color> {
1010

1111
override val descriptor: SerialDescriptor =
12-
buildClassSerialDescriptor("Color") {
12+
buildClassSerialDescriptor("my.app.Color") {
1313
element<Int>("r")
1414
element<Int>("g")
1515
element<Int>("b")

guide/example/example-serializer-14.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import java.util.Date
1010
import java.text.SimpleDateFormat
1111

1212
object DateAsLongSerializer : KSerializer<Date> {
13-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
13+
// Serial names of descriptors should be unique, so choose app-specific name in case some library also would declare a serializer for Date.
14+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1415
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1516
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1617
}

guide/example/example-serializer-15.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.util.Date
1010
import java.text.SimpleDateFormat
1111

1212
object DateAsLongSerializer : KSerializer<Date> {
13-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
13+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1414
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1515
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1616
}

guide/example/example-serializer-16.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.util.Date
1010
import java.text.SimpleDateFormat
1111

1212
object DateAsLongSerializer : KSerializer<Date> {
13-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
13+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1414
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1515
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1616
}

guide/example/example-serializer-17.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import java.util.Date
1111
import java.text.SimpleDateFormat
1212

1313
object DateAsLongSerializer : KSerializer<Date> {
14-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
14+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1515
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1616
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1717
}

guide/example/example-serializer-18.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import java.util.TimeZone
1111
import java.text.SimpleDateFormat
1212

1313
object DateAsLongSerializer : KSerializer<Date> {
14-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("DateAsLong", PrimitiveKind.LONG)
14+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1515
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1616
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1717
}
1818

1919
object DateAsSimpleTextSerializer: KSerializer<Date> {
20-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("DateAsSimpleText", PrimitiveKind.LONG)
20+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsSimpleText", PrimitiveKind.LONG)
2121
private val format = SimpleDateFormat("yyyy-MM-dd").apply {
2222
// Here we explicitly set time zone to UTC so output for this sample remains locale-independent.
2323
// Depending on your needs, you may have to adjust or remove this line.

guide/example/example-serializer-19.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import kotlinx.serialization.descriptors.*
1010
data class Box<T>(val contents: T)
1111

1212
class BoxSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<Box<T>> {
13-
override val descriptor: SerialDescriptor = dataSerializer.descriptor
13+
override val descriptor: SerialDescriptor = SerialDescriptor("my.app.Box", dataSerializer.descriptor)
1414
override fun serialize(encoder: Encoder, value: Box<T>) = dataSerializer.serialize(encoder, value.contents)
1515
override fun deserialize(decoder: Decoder) = Box(dataSerializer.deserialize(decoder))
1616
}

guide/example/example-serializer-20.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import kotlinx.serialization.encoding.*
77
import kotlinx.serialization.descriptors.*
88

99
object ColorAsStringSerializer : KSerializer<Color> {
10-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Color", PrimitiveKind.STRING)
10+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.Color", PrimitiveKind.STRING)
1111

1212
override fun serialize(encoder: Encoder, value: Color) {
1313
val string = value.rgb.toString(16).padStart(6, '0')

guide/example/example-serializer-22.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import java.util.Date
1111
import java.text.SimpleDateFormat
1212

1313
object DateAsLongSerializer : KSerializer<Date> {
14-
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
14+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.app.DateAsLong", PrimitiveKind.LONG)
1515
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
1616
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
1717
}

0 commit comments

Comments
 (0)