Skip to content

Commit

Permalink
Ensure different serial names for incompatible serializers
Browse files Browse the repository at this point in the history
Fixes #416
  • Loading branch information
dkhalanskyjb committed Jul 25, 2024
1 parent aec4a6c commit f678d42
Show file tree
Hide file tree
Showing 13 changed files with 46 additions and 29 deletions.
9 changes: 6 additions & 3 deletions core/common/src/DateTimePeriod.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import kotlinx.datetime.internal.*
import kotlinx.datetime.serializers.DatePeriodIso8601Serializer
import kotlinx.datetime.serializers.DateTimePeriodIso8601Serializer
import kotlinx.datetime.serializers.DatePeriodComponentSerializer
import kotlinx.datetime.serializers.DatePeriodSerializer
import kotlinx.datetime.serializers.DateTimePeriodComponentSerializer
import kotlinx.datetime.serializers.DateTimePeriodSerializer
import kotlin.math.*
import kotlin.time.Duration
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -63,13 +65,14 @@ import kotlinx.serialization.Serializable
* `DateTimePeriod` can also be returned as the result of instant arithmetic operations (see [Instant.periodUntil]).
*
* Additionally, there are several `kotlinx-serialization` serializers for [DateTimePeriod]:
* - [DateTimePeriodIso8601Serializer] for the ISO 8601 format;
* - The default serializer, delegating to [toString] and [parse].
* - [DateTimePeriodIso8601Serializer] for the ISO 8601 format.
* - [DateTimePeriodComponentSerializer] for an object with components.
*
* @sample kotlinx.datetime.test.samples.DateTimePeriodSamples.construction
* @sample kotlinx.datetime.test.samples.DateTimePeriodSamples.simpleParsingAndFormatting
*/
@Serializable(with = DateTimePeriodIso8601Serializer::class)
@Serializable(with = DateTimePeriodSerializer::class)
// TODO: could be error-prone without explicitly named params
public sealed class DateTimePeriod {
internal abstract val totalMonths: Int
Expand Down Expand Up @@ -426,7 +429,7 @@ public fun String.toDateTimePeriod(): DateTimePeriod = DateTimePeriod.parse(this
*
* @sample kotlinx.datetime.test.samples.DatePeriodSamples.simpleParsingAndFormatting
*/
@Serializable(with = DatePeriodIso8601Serializer::class)
@Serializable(with = DatePeriodSerializer::class)
public class DatePeriod internal constructor(
internal override val totalMonths: Int,
override val days: Int,
Expand Down
20 changes: 16 additions & 4 deletions core/common/src/serializers/DateTimePeriodSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.serialization.encoding.*
public object DateTimePeriodComponentSerializer: KSerializer<DateTimePeriod> {

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.DateTimePeriod") {
buildClassSerialDescriptor("kotlinx.datetime.DateTimePeriod components") {
element<Int>("years", isOptional = true)
element<Int>("months", isOptional = true)
element<Int>("days", isOptional = true)
Expand Down Expand Up @@ -81,7 +81,7 @@ public object DateTimePeriodComponentSerializer: KSerializer<DateTimePeriod> {
public object DateTimePeriodIso8601Serializer: KSerializer<DateTimePeriod> {

override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("kotlinx.datetime.DateTimePeriod", PrimitiveKind.STRING)
PrimitiveSerialDescriptor("kotlinx.datetime.DateTimePeriod ISO", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): DateTimePeriod =
DateTimePeriod.parse(decoder.decodeString())
Expand Down Expand Up @@ -110,7 +110,7 @@ public object DatePeriodComponentSerializer: KSerializer<DatePeriod> {
private fun unexpectedNonzero(fieldName: String, value: Int) = unexpectedNonzero(fieldName, value.toLong())

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.DatePeriod") {
buildClassSerialDescriptor("kotlinx.datetime.DatePeriod components") {
element<Int>("years", isOptional = true)
element<Int>("months", isOptional = true)
element<Int>("days", isOptional = true)
Expand Down Expand Up @@ -166,7 +166,7 @@ public object DatePeriodComponentSerializer: KSerializer<DatePeriod> {
public object DatePeriodIso8601Serializer: KSerializer<DatePeriod> {

override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("kotlinx.datetime.DatePeriod", PrimitiveKind.STRING)
PrimitiveSerialDescriptor("kotlinx.datetime.DatePeriod ISO", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): DatePeriod =
when (val period = DateTimePeriod.parse(decoder.decodeString())) {
Expand All @@ -179,3 +179,15 @@ public object DatePeriodIso8601Serializer: KSerializer<DatePeriod> {
}

}

@PublishedApi
internal object DateTimePeriodSerializer: KSerializer<DateTimePeriod> by DateTimePeriodIso8601Serializer {
override val descriptor =
PrimitiveSerialDescriptor("kotlinx.datetime.DateTimePeriod", PrimitiveKind.STRING)
}

@PublishedApi
internal object DatePeriodSerializer: KSerializer<DatePeriod> by DatePeriodIso8601Serializer {
override val descriptor =
PrimitiveSerialDescriptor("kotlinx.datetime.DatePeriod", PrimitiveKind.STRING)
}
4 changes: 2 additions & 2 deletions core/common/src/serializers/InstantSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import kotlinx.serialization.encoding.*
public object InstantIso8601Serializer : KSerializer<Instant> {

override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("kotlinx.datetime.Instant", PrimitiveKind.STRING)
PrimitiveSerialDescriptor("kotlinx.datetime.Instant ISO", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): Instant =
Instant.parse(decoder.decodeString(), DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET)
Expand All @@ -41,7 +41,7 @@ public object InstantIso8601Serializer : KSerializer<Instant> {
public object InstantComponentSerializer : KSerializer<Instant> {

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.Instant") {
buildClassSerialDescriptor("kotlinx.datetime.Instant components") {
element<Long>("epochSeconds")
element<Long>("nanosecondsOfSecond", isOptional = true)
}
Expand Down
4 changes: 2 additions & 2 deletions core/common/src/serializers/LocalDateSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.serialization.encoding.*
* @see LocalDate.Formats.ISO
*/
public object LocalDateIso8601Serializer : KSerializer<LocalDate>
by LocalDate.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDate")
by LocalDate.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDate ISO")

/**
* A serializer for [LocalDate] that represents a value as its components.
Expand All @@ -29,7 +29,7 @@ by LocalDate.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDate")
public object LocalDateComponentSerializer: KSerializer<LocalDate> {

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.LocalDate") {
buildClassSerialDescriptor("kotlinx.datetime.LocalDate components") {
element<Int>("year")
element<Short>("month")
element<Short>("day")
Expand Down
4 changes: 2 additions & 2 deletions core/common/src/serializers/LocalDateTimeSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.serialization.encoding.*
* @see LocalDateTime.Formats.ISO
*/
public object LocalDateTimeIso8601Serializer : KSerializer<LocalDateTime>
by LocalDateTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDateTime")
by LocalDateTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDateTime ISO")

/**
* A serializer for [LocalDateTime] that represents a value as its components.
Expand All @@ -29,7 +29,7 @@ by LocalDateTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalDateTime")
public object LocalDateTimeComponentSerializer: KSerializer<LocalDateTime> {

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.LocalDateTime") {
buildClassSerialDescriptor("kotlinx.datetime.LocalDateTime components") {
element<Int>("year")
element<Short>("month")
element<Short>("day")
Expand Down
4 changes: 2 additions & 2 deletions core/common/src/serializers/LocalTimeSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.serialization.encoding.*
* @see LocalTime.Formats.ISO
*/
public object LocalTimeIso8601Serializer : KSerializer<LocalTime>
by LocalTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalTime")
by LocalTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalTime ISO")

/**
* A serializer for [LocalTime] that represents a value as its components.
Expand All @@ -29,7 +29,7 @@ by LocalTime.Formats.ISO.asKSerializer("kotlinx.datetime.LocalTime")
public object LocalTimeComponentSerializer : KSerializer<LocalTime> {

override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("kotlinx.datetime.LocalTime") {
buildClassSerialDescriptor("kotlinx.datetime.LocalTime components") {
element<Short>("hour")
element<Short>("minute")
element<Short>("second", isOptional = true)
Expand Down
2 changes: 1 addition & 1 deletion core/common/src/serializers/TimeZoneSerializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public object FixedOffsetTimeZoneSerializer: KSerializer<FixedOffsetTimeZone> {
* @see UtcOffset.Formats.ISO
*/
public object UtcOffsetIso8601Serializer : KSerializer<UtcOffset>
by UtcOffset.Formats.ISO.asKSerializer("kotlinx.datetime.UtcOffset")
by UtcOffset.Formats.ISO.asKSerializer("kotlinx.datetime.UtcOffset ISO")

/**
* A serializer for [UtcOffset] that uses the default [UtcOffset.toString]/[UtcOffset.parse].
Expand Down
8 changes: 4 additions & 4 deletions serialization/common/test/DateTimePeriodSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,25 +97,25 @@ class DateTimePeriodSerializationTest {

@Test
fun testDatePeriodIso8601Serialization() {
assertKSerializerName("kotlinx.datetime.DatePeriod", DatePeriodIso8601Serializer)
assertKSerializerName("kotlinx.datetime.DatePeriod ISO", DatePeriodIso8601Serializer)
datePeriodIso8601Serialization(DatePeriodIso8601Serializer, DateTimePeriodIso8601Serializer)
}

@Test
fun testDatePeriodComponentSerialization() {
assertKSerializerName("kotlinx.datetime.DatePeriod", DatePeriodComponentSerializer)
assertKSerializerName("kotlinx.datetime.DatePeriod components", DatePeriodComponentSerializer)
datePeriodComponentSerialization(DatePeriodComponentSerializer, DateTimePeriodComponentSerializer)
}

@Test
fun testDateTimePeriodIso8601Serialization() {
assertKSerializerName("kotlinx.datetime.DateTimePeriod", DateTimePeriodIso8601Serializer)
assertKSerializerName("kotlinx.datetime.DateTimePeriod ISO", DateTimePeriodIso8601Serializer)
dateTimePeriodIso8601Serialization(DateTimePeriodIso8601Serializer)
}

@Test
fun testDateTimePeriodComponentSerialization() {
assertKSerializerName("kotlinx.datetime.DateTimePeriod", DateTimePeriodComponentSerializer)
assertKSerializerName("kotlinx.datetime.DateTimePeriod components", DateTimePeriodComponentSerializer)
dateTimePeriodComponentSerialization(DateTimePeriodComponentSerializer)
}

Expand Down
4 changes: 2 additions & 2 deletions serialization/common/test/InstantSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ class InstantSerializationTest {

@Test
fun testIso8601Serialization() {
assertKSerializerName("kotlinx.datetime.Instant", InstantIso8601Serializer)
assertKSerializerName("kotlinx.datetime.Instant ISO", InstantIso8601Serializer)
iso8601Serialization(InstantIso8601Serializer)
}

@Test
fun testComponentSerialization() {
assertKSerializerName("kotlinx.datetime.Instant", InstantComponentSerializer)
assertKSerializerName("kotlinx.datetime.Instant components", InstantComponentSerializer)
componentSerialization(InstantComponentSerializer)
}

Expand Down
4 changes: 2 additions & 2 deletions serialization/common/test/LocalDateSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ class LocalDateSerializationTest {

@Test
fun testIso8601Serialization() {
assertKSerializerName("kotlinx.datetime.LocalDate", LocalDateIso8601Serializer)
assertKSerializerName("kotlinx.datetime.LocalDate ISO", LocalDateIso8601Serializer)
iso8601Serialization(LocalDateIso8601Serializer)
}

@Test
fun testComponentSerialization() {
assertKSerializerName("kotlinx.datetime.LocalDate", LocalDateComponentSerializer)
assertKSerializerName("kotlinx.datetime.LocalDate components", LocalDateComponentSerializer)
componentSerialization(LocalDateComponentSerializer)
}

Expand Down
6 changes: 4 additions & 2 deletions serialization/common/test/LocalDateTimeSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ class LocalDateTimeSerializationTest {

@Test
fun testIso8601Serialization() {
assertKSerializerName<LocalDateTime>("kotlinx.datetime.LocalDateTime", LocalDateTimeComponentSerializer)
assertKSerializerName<LocalDateTime>("kotlinx.datetime.LocalDateTime ISO", LocalDateTimeIso8601Serializer)
iso8601Serialization(LocalDateTimeIso8601Serializer)
}

@Test
fun testComponentSerialization() {
assertKSerializerName<LocalDateTime>("kotlinx.datetime.LocalDateTime", LocalDateTimeComponentSerializer)
assertKSerializerName<LocalDateTime>(
"kotlinx.datetime.LocalDateTime components", LocalDateTimeComponentSerializer
)
componentSerialization(LocalDateTimeComponentSerializer)
}

Expand Down
4 changes: 2 additions & 2 deletions serialization/common/test/LocalTimeSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ class LocalTimeSerializationTest {

@Test
fun testIso8601Serialization() {
assertKSerializerName("kotlinx.datetime.LocalTime", LocalTimeIso8601Serializer)
assertKSerializerName("kotlinx.datetime.LocalTime ISO", LocalTimeIso8601Serializer)
iso8601Serialization(LocalTimeIso8601Serializer)
}

@Test
fun testComponentSerialization() {
assertKSerializerName("kotlinx.datetime.LocalTime", LocalTimeComponentSerializer)
assertKSerializerName("kotlinx.datetime.LocalTime components", LocalTimeComponentSerializer)
componentSerialization(LocalTimeComponentSerializer)
}

Expand Down
2 changes: 1 addition & 1 deletion serialization/common/test/UtcOffsetSerializationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class UtcOffsetSerializationTest {

@Test
fun testIso8601Serialization() {
assertKSerializerName<UtcOffset>("kotlinx.datetime.UtcOffset", UtcOffsetIso8601Serializer)
assertKSerializerName<UtcOffset>("kotlinx.datetime.UtcOffset ISO", UtcOffsetIso8601Serializer)
iso8601Serialization(UtcOffsetIso8601Serializer)
}

Expand Down

0 comments on commit f678d42

Please sign in to comment.