You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When integrating custom adapters and annotations with kotlin.time.Duration, the expected behavior is for the adapter to accurately convert JSON's long values into Kotlin's Duration type. However, I've observed that the deserialization process doesn't work as expected. Instead of obtaining a Duration object, the output remains as a Long type. This issue seems to occur during the deserialization process, indicating a potential problem in the handling of Kotlin's Duration type.
Here is the adapter and annotations created:
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class DurationMillis
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class DurationSeconds
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class DurationMinutes
object DurationJsonAdapter {
@ToJson
fun millisToJson(@DurationMillis duration: Duration): Long = duration.inWholeMilliseconds
@FromJson
@DurationMillis
fun millisFromJson(value: Long): Duration = value.milliseconds
@ToJson
fun secondsToJson(@DurationSeconds duration: Duration): Long = duration.inWholeSeconds
@FromJson
@DurationSeconds
fun secondsFromJson(value: Long): Duration = value.seconds
@ToJson
fun minutesToJson(@DurationMinutes duration: Duration): Long = duration.inWholeMinutes
@FromJson
@DurationMinutes
fun minutesFromJson(value: Long): Duration = value.minutes
}
with some tests included:
class DurationJsonAdapterTest {
@JsonClass(generateAdapter = true)
data class DurationTypes(
@Json(name = "durationMillis") @DurationMillis val durationMillis: Duration,
@Json(name = "durationSeconds") @DurationSeconds val durationSeconds: Duration,
@Json(name = "durationMinutes") @DurationMinutes val durationMinutes: Duration,
)
private val moshi = Moshi.Builder()
.add(DurationJsonAdapter)
.build()
@OptIn(ExperimentalStdlibApi::class)
@Test
fun fromJson() {
val adapter = moshi.adapter<DurationTypes>()
val json = """{"durationMillis": 120000, "durationSeconds": 120, "durationMinutes": 2}"""
val javanDuration = adapter.fromJson(json)
assertEquals(2.minutes, javanDuration?.durationMillis)
assertEquals(2.minutes, javanDuration?.durationSeconds)
assertEquals(2.minutes, javanDuration?.durationMinutes)
}
@OptIn(ExperimentalStdlibApi::class)
@Test
fun toJson() {
val adapter: JsonAdapter<DurationTypes> = moshi.adapter<DurationTypes>()
val javanDuration = DurationTypes(2.minutes, 2.minutes, 2.minutes)
val json = adapter.toJson(javanDuration)
assertEquals("""{"durationMillis":120000, "durationSeconds":120, "durationMinutes":2}""", json)
}
}
The output:
Inspecting the factories:
With Java Duration (java.time.Duration) works perfectly well
class JavaDurationJsonAdapterTest {
@JsonClass(generateAdapter = true)
data class DurationTypes(
@Json(name = "durationMillis") @JavaDurationMillis val durationMillis: JavaDuration,
@Json(name = "durationSeconds") @JavaDurationSeconds val durationSeconds: JavaDuration,
@Json(name = "durationMinutes") @JavaDurationMinutes val durationMinutes: JavaDuration,
)
private val moshi = Moshi.Builder()
.add(JavaDurationJsonAdapter)
.build()
@OptIn(ExperimentalStdlibApi::class)
@Test
fun fromJson() {
val adapter = moshi.adapter<DurationTypes>()
val json = """{"durationMillis": 120000, "durationSeconds": 120, "durationMinutes": 2}"""
val javanDuration = adapter.fromJson(json)
assertEquals(JavaDuration.ofMinutes(2), javanDuration?.durationMillis)
assertEquals(JavaDuration.ofMinutes(2), javanDuration?.durationSeconds)
assertEquals(JavaDuration.ofMinutes(2), javanDuration?.durationMinutes)
}
@OptIn(ExperimentalStdlibApi::class)
@Test
fun toJson() {
val adapter: JsonAdapter<DurationTypes> = moshi.adapter<DurationTypes>()
val javanDuration = DurationTypes(JavaDuration.ofMinutes(2), JavaDuration.ofMinutes(2), JavaDuration.ofMinutes(2))
val json = adapter.toJson(javanDuration)
assertEquals("""{"durationMillis":120000,"durationSeconds":120,"durationMinutes":2}""", json)
}
}
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class JavaDurationMillis
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class JavaDurationSeconds
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class JavaDurationMinutes
object JavaDurationJsonAdapter {
@ToJson
fun millisToJson(@JavaDurationMillis duration: JavaDuration): Long = duration.toMillis()
@FromJson
@JavaDurationMillis
fun millisFromJson(value: Long): JavaDuration = JavaDuration.ofMillis(value)
@ToJson
fun secondsToJson(@JavaDurationSeconds duration: JavaDuration): Long = duration.toSeconds()
@FromJson
@JavaDurationSeconds
fun secondsFromJson(value: Long): JavaDuration = JavaDuration.ofSeconds(value)
@ToJson
fun minutesToJson(@JavaDurationMinutes duration: JavaDuration): Long = duration.toMinutes()
@FromJson
@JavaDurationMinutes
fun minutesFromJson(value: Long): JavaDuration = JavaDuration.ofMinutes(value)
}
The text was updated successfully, but these errors were encountered:
When integrating custom adapters and annotations with kotlin.time.Duration, the expected behavior is for the adapter to accurately convert JSON's long values into Kotlin's Duration type. However, I've observed that the deserialization process doesn't work as expected. Instead of obtaining a Duration object, the output remains as a Long type. This issue seems to occur during the deserialization process, indicating a potential problem in the handling of Kotlin's Duration type.
Here is the adapter and annotations created:
with some tests included:
The output:
Inspecting the factories:
With Java Duration (
java.time.Duration
) works perfectly wellThe text was updated successfully, but these errors were encountered: