diff --git a/core/api/kotlinx-serialization-core.api b/core/api/kotlinx-serialization-core.api index 5cddb226d..3bf89f7fe 100644 --- a/core/api/kotlinx-serialization-core.api +++ b/core/api/kotlinx-serialization-core.api @@ -170,6 +170,10 @@ public final class kotlinx/serialization/builtins/BuiltinSerializersKt { public static final fun SetSerializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; public static final fun ShortArraySerializer ()Lkotlinx/serialization/KSerializer; public static final fun TripleSerializer (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; + public static final fun UByteArraySerializer ()Lkotlinx/serialization/KSerializer; + public static final fun UIntArraySerializer ()Lkotlinx/serialization/KSerializer; + public static final fun ULongArraySerializer ()Lkotlinx/serialization/KSerializer; + public static final fun UShortArraySerializer ()Lkotlinx/serialization/KSerializer; public static final fun getNullable (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; public static final fun serializer (Lkotlin/UByte$Companion;)Lkotlinx/serialization/KSerializer; public static final fun serializer (Lkotlin/UInt$Companion;)Lkotlinx/serialization/KSerializer; @@ -1151,6 +1155,20 @@ public final class kotlinx/serialization/internal/TripleSerializer : kotlinx/ser public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lkotlin/Triple;)V } +public final class kotlinx/serialization/internal/UByteArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { + public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; +} + +public final class kotlinx/serialization/internal/UByteArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer { + public static final field INSTANCE Lkotlinx/serialization/internal/UByteArraySerializer; + public synthetic fun collectionSize (Ljava/lang/Object;)I + public synthetic fun empty ()Ljava/lang/Object; + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V + public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V +} + public final class kotlinx/serialization/internal/UByteSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Lkotlinx/serialization/internal/UByteSerializer; public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; @@ -1160,6 +1178,20 @@ public final class kotlinx/serialization/internal/UByteSerializer : kotlinx/seri public fun serialize-EK-6454 (Lkotlinx/serialization/encoding/Encoder;B)V } +public final class kotlinx/serialization/internal/UIntArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { + public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; +} + +public final class kotlinx/serialization/internal/UIntArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer { + public static final field INSTANCE Lkotlinx/serialization/internal/UIntArraySerializer; + public synthetic fun collectionSize (Ljava/lang/Object;)I + public synthetic fun empty ()Ljava/lang/Object; + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V + public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V +} + public final class kotlinx/serialization/internal/UIntSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Lkotlinx/serialization/internal/UIntSerializer; public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; @@ -1169,6 +1201,20 @@ public final class kotlinx/serialization/internal/UIntSerializer : kotlinx/seria public fun serialize-Qn1smSk (Lkotlinx/serialization/encoding/Encoder;I)V } +public final class kotlinx/serialization/internal/ULongArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { + public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; +} + +public final class kotlinx/serialization/internal/ULongArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer { + public static final field INSTANCE Lkotlinx/serialization/internal/ULongArraySerializer; + public synthetic fun collectionSize (Ljava/lang/Object;)I + public synthetic fun empty ()Ljava/lang/Object; + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V + public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V +} + public final class kotlinx/serialization/internal/ULongSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Lkotlinx/serialization/internal/ULongSerializer; public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; @@ -1178,6 +1224,20 @@ public final class kotlinx/serialization/internal/ULongSerializer : kotlinx/seri public fun serialize-2TYgG_w (Lkotlinx/serialization/encoding/Encoder;J)V } +public final class kotlinx/serialization/internal/UShortArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder { + public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object; +} + +public final class kotlinx/serialization/internal/UShortArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer { + public static final field INSTANCE Lkotlinx/serialization/internal/UShortArraySerializer; + public synthetic fun collectionSize (Ljava/lang/Object;)I + public synthetic fun empty ()Ljava/lang/Object; + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V + public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V + public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V +} + public final class kotlinx/serialization/internal/UShortSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Lkotlinx/serialization/internal/UShortSerializer; public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; diff --git a/core/commonMain/src/kotlinx/serialization/builtins/BuiltinSerializers.kt b/core/commonMain/src/kotlinx/serialization/builtins/BuiltinSerializers.kt index 19698c459..10f3f86ca 100644 --- a/core/commonMain/src/kotlinx/serialization/builtins/BuiltinSerializers.kt +++ b/core/commonMain/src/kotlinx/serialization/builtins/BuiltinSerializers.kt @@ -74,6 +74,14 @@ public fun Byte.Companion.serializer(): KSerializer = ByteSerializer */ public fun ByteArraySerializer(): KSerializer = ByteArraySerializer +/** + * Returns serializer for [UByteArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind. + * Each element of the array is serialized one by one with [UByte.Companion.serializer]. + */ +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +public fun UByteArraySerializer(): KSerializer = UByteArraySerializer + /** * Returns serializer for [Short] with [descriptor][SerialDescriptor] of [PrimitiveKind.SHORT] kind. */ @@ -85,6 +93,14 @@ public fun Short.Companion.serializer(): KSerializer = ShortSerializer */ public fun ShortArraySerializer(): KSerializer = ShortArraySerializer +/** + * Returns serializer for [UShortArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind. + * Each element of the array is serialized one by one with [UShort.Companion.serializer]. + */ +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +public fun UShortArraySerializer(): KSerializer = UShortArraySerializer + /** * Returns serializer for [Int] with [descriptor][SerialDescriptor] of [PrimitiveKind.INT] kind. */ @@ -96,6 +112,14 @@ public fun Int.Companion.serializer(): KSerializer = IntSerializer */ public fun IntArraySerializer(): KSerializer = IntArraySerializer +/** + * Returns serializer for [UIntArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind. + * Each element of the array is serialized one by one with [UInt.Companion.serializer]. + */ +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +public fun UIntArraySerializer(): KSerializer = UIntArraySerializer + /** * Returns serializer for [Long] with [descriptor][SerialDescriptor] of [PrimitiveKind.LONG] kind. */ @@ -107,6 +131,14 @@ public fun Long.Companion.serializer(): KSerializer = LongSerializer */ public fun LongArraySerializer(): KSerializer = LongArraySerializer +/** + * Returns serializer for [ULongArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind. + * Each element of the array is serialized one by one with [ULong.Companion.serializer]. + */ +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +public fun ULongArraySerializer(): KSerializer = ULongArraySerializer + /** * Returns serializer for [Float] with [descriptor][SerialDescriptor] of [PrimitiveKind.FLOAT] kind. */ diff --git a/core/commonMain/src/kotlinx/serialization/internal/PrimitiveArraysSerializers.kt b/core/commonMain/src/kotlinx/serialization/internal/PrimitiveArraysSerializers.kt index 7427b1606..1e6172f0b 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/PrimitiveArraysSerializers.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/PrimitiveArraysSerializers.kt @@ -408,3 +408,223 @@ internal class BooleanArrayBuilder internal constructor( override fun build() = buffer.copyOf(position) } + + +// Unsigned arrays + +/** + * Serializer for [UByteArray]. + * + * Encode elements one-by-one, as regular list, + * unless format's Encoder/Decoder have special handling for this serializer. + */ +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal object UByteArraySerializer : KSerializer, + PrimitiveArraySerializer(UByte.serializer()) { + + override fun UByteArray.collectionSize(): Int = size + override fun UByteArray.toBuilder(): UByteArrayBuilder = UByteArrayBuilder(this) + override fun empty(): UByteArray = UByteArray(0) + + override fun readElement(decoder: CompositeDecoder, index: Int, builder: UByteArrayBuilder, checkIndex: Boolean) { + builder.append(decoder.decodeInlineElement(descriptor, index).decodeByte().toUByte()) + } + + override fun writeContent(encoder: CompositeEncoder, content: UByteArray, size: Int) { + for (i in 0 until size) + encoder.encodeInlineElement(descriptor, i).encodeByte(content[i].toByte()) + } +} + +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal class UByteArrayBuilder internal constructor( + bufferWithData: UByteArray +) : PrimitiveArrayBuilder() { + + private var buffer: UByteArray = bufferWithData + override var position: Int = bufferWithData.size + private set + + init { + ensureCapacity(INITIAL_SIZE) + } + + override fun ensureCapacity(requiredCapacity: Int) { + if (buffer.size < requiredCapacity) + buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2)) + } + + internal fun append(c: UByte) { + ensureCapacity() + buffer[position++] = c + } + + override fun build() = buffer.copyOf(position) +} + +/** + * Serializer for [UShortArray]. + * + * Encode elements one-by-one, as regular list, + * unless format's Encoder/Decoder have special handling for this serializer. + */ +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal object UShortArraySerializer : KSerializer, + PrimitiveArraySerializer(UShort.serializer()) { + + override fun UShortArray.collectionSize(): Int = size + override fun UShortArray.toBuilder(): UShortArrayBuilder = UShortArrayBuilder(this) + override fun empty(): UShortArray = UShortArray(0) + + override fun readElement(decoder: CompositeDecoder, index: Int, builder: UShortArrayBuilder, checkIndex: Boolean) { + builder.append(decoder.decodeInlineElement(descriptor, index).decodeShort().toUShort()) + } + + override fun writeContent(encoder: CompositeEncoder, content: UShortArray, size: Int) { + for (i in 0 until size) + encoder.encodeInlineElement(descriptor, i).encodeShort(content[i].toShort()) + } +} + +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal class UShortArrayBuilder internal constructor( + bufferWithData: UShortArray +) : PrimitiveArrayBuilder() { + + private var buffer: UShortArray = bufferWithData + override var position: Int = bufferWithData.size + private set + + init { + ensureCapacity(INITIAL_SIZE) + } + + override fun ensureCapacity(requiredCapacity: Int) { + if (buffer.size < requiredCapacity) + buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2)) + } + + internal fun append(c: UShort) { + ensureCapacity() + buffer[position++] = c + } + + override fun build() = buffer.copyOf(position) +} + +/** + * Serializer for [UIntArray]. + * + * Encode elements one-by-one, as regular list, + * unless format's Encoder/Decoder have special handling for this serializer. + */ +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal object UIntArraySerializer : KSerializer, + PrimitiveArraySerializer(UInt.serializer()) { + + override fun UIntArray.collectionSize(): Int = size + override fun UIntArray.toBuilder(): UIntArrayBuilder = UIntArrayBuilder(this) + override fun empty(): UIntArray = UIntArray(0) + + override fun readElement(decoder: CompositeDecoder, index: Int, builder: UIntArrayBuilder, checkIndex: Boolean) { + builder.append(decoder.decodeInlineElement(descriptor, index).decodeInt().toUInt()) + } + + override fun writeContent(encoder: CompositeEncoder, content: UIntArray, size: Int) { + for (i in 0 until size) + encoder.encodeInlineElement(descriptor, i).encodeInt(content[i].toInt()) + } +} + +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal class UIntArrayBuilder internal constructor( + bufferWithData: UIntArray +) : PrimitiveArrayBuilder() { + + private var buffer: UIntArray = bufferWithData + override var position: Int = bufferWithData.size + private set + + init { + ensureCapacity(INITIAL_SIZE) + } + + override fun ensureCapacity(requiredCapacity: Int) { + if (buffer.size < requiredCapacity) + buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2)) + } + + internal fun append(c: UInt) { + ensureCapacity() + buffer[position++] = c + } + + override fun build() = buffer.copyOf(position) +} + +/** + * Serializer for [ULongArray]. + * + * Encode elements one-by-one, as regular list, + * unless format's Encoder/Decoder have special handling for this serializer. + */ +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal object ULongArraySerializer : KSerializer, + PrimitiveArraySerializer(ULong.serializer()) { + + override fun ULongArray.collectionSize(): Int = size + override fun ULongArray.toBuilder(): ULongArrayBuilder = ULongArrayBuilder(this) + override fun empty(): ULongArray = ULongArray(0) + + override fun readElement(decoder: CompositeDecoder, index: Int, builder: ULongArrayBuilder, checkIndex: Boolean) { + builder.append(decoder.decodeInlineElement(descriptor, index).decodeLong().toULong()) + } + + override fun writeContent(encoder: CompositeEncoder, content: ULongArray, size: Int) { + for (i in 0 until size) + encoder.encodeInlineElement(descriptor, i).encodeLong(content[i].toLong()) + } +} + +@PublishedApi +@ExperimentalSerializationApi +@ExperimentalUnsignedTypes +internal class ULongArrayBuilder internal constructor( + bufferWithData: ULongArray +) : PrimitiveArrayBuilder() { + + private var buffer: ULongArray = bufferWithData + override var position: Int = bufferWithData.size + private set + + init { + ensureCapacity(INITIAL_SIZE) + } + + override fun ensureCapacity(requiredCapacity: Int) { + if (buffer.size < requiredCapacity) + buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2)) + } + + internal fun append(c: ULong) { + ensureCapacity() + buffer[position++] = c + } + + override fun build() = buffer.copyOf(position) +} + diff --git a/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt b/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt index dfc9aafa7..5de1fe2fe 100644 --- a/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt +++ b/core/commonMain/src/kotlinx/serialization/internal/Primitives.kt @@ -15,6 +15,7 @@ import kotlin.native.concurrent.* import kotlin.reflect.* import kotlin.time.Duration +@OptIn(ExperimentalUnsignedTypes::class) @SharedImmutable private val BUILTIN_SERIALIZERS = mapOf( String::class to String.serializer(), @@ -26,12 +27,20 @@ private val BUILTIN_SERIALIZERS = mapOf( FloatArray::class to FloatArraySerializer(), Long::class to Long.serializer(), LongArray::class to LongArraySerializer(), + ULong::class to ULong.serializer(), + ULongArray::class to ULongArraySerializer(), Int::class to Int.serializer(), IntArray::class to IntArraySerializer(), + UInt::class to UInt.serializer(), + UIntArray::class to UIntArraySerializer(), Short::class to Short.serializer(), ShortArray::class to ShortArraySerializer(), + UShort::class to UShort.serializer(), + UShortArray::class to UShortArraySerializer(), Byte::class to Byte.serializer(), ByteArray::class to ByteArraySerializer(), + UByte::class to UByte.serializer(), + UByteArray::class to UByteArraySerializer(), Boolean::class to Boolean.serializer(), BooleanArray::class to BooleanArraySerializer(), Unit::class to Unit.serializer(), diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt index c5dcf2016..95b458c9e 100644 --- a/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt @@ -52,6 +52,21 @@ class SerializersLookupTest : JsonTestBase() { assertSerializedWithType("""["a","b","c"]""", myArr) } + @Test + fun testUnsigned() = noLegacyJs { + assertSame(UByte.serializer(), serializer()) + assertSame(UShort.serializer(), serializer()) + assertSame(UInt.serializer(), serializer()) + assertSame(ULong.serializer(), serializer()) + } + @Test + @OptIn(ExperimentalUnsignedTypes::class) + fun testUnsignedArrays() { + assertSame(UByteArraySerializer(), serializer()) + assertSame(UShortArraySerializer(), serializer()) + assertSame(UIntArraySerializer(), serializer()) + assertSame(ULongArraySerializer(), serializer()) + } @Test fun testPrimitiveSet() { diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/UnsignedIntegersTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/UnsignedIntegersTest.kt index 3611fc27a..c01d15409 100644 --- a/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/UnsignedIntegersTest.kt +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/features/inline/UnsignedIntegersTest.kt @@ -5,6 +5,7 @@ package kotlinx.serialization.features.inline import kotlinx.serialization.* +import kotlinx.serialization.builtins.* import kotlinx.serialization.json.* import kotlin.test.* @@ -20,6 +21,37 @@ class UnsignedIntegersTest : JsonTestBase() { val double: Double ) +// TODO uncomment when Kotlin 1.8.0 is released +// @Serializable +// data class UnsignedArrays( +// val uByte: UByteArray, +// val uShort: UShortArray, +// val uInt: UIntArray, +// val uLong: ULongArray +// ) { +// override fun equals(other: Any?): Boolean { +// if (this === other) return true +// if (other == null || this::class != other::class) return false +// +// other as UnsignedArrays +// +// if (!uByte.contentEquals(other.uByte)) return false +// if (!uShort.contentEquals(other.uShort)) return false +// if (!uInt.contentEquals(other.uInt)) return false +// if (!uLong.contentEquals(other.uLong)) return false +// +// return true +// } +// +// override fun hashCode(): Int { +// var result = uByte.contentHashCode() +// result = 31 * result + uShort.contentHashCode() +// result = 31 * result + uInt.contentHashCode() +// result = 31 * result + uLong.contentHashCode() +// return result +// } +// } + @Serializable data class UnsignedWithoutLong(val uInt: UInt, val uByte: UByte, val uShort: UShort) @@ -54,4 +86,55 @@ class UnsignedIntegersTest : JsonTestBase() { """{"uInt":2147483657,"uByte":239,"uShort":65000}""", ) } + + @Test + fun testRoot() { + assertJsonFormAndRestored(UByte.serializer(), 220U, "220") + assertJsonFormAndRestored(UShort.serializer(), 65000U, "65000") + assertJsonFormAndRestored(UInt.serializer(), 2147483657U, "2147483657") + assertJsonFormAndRestored(ULong.serializer(), 9223372036854775817U, "9223372036854775817") + } + + @OptIn(ExperimentalUnsignedTypes::class) + @Test + fun testRootArrays() = parametrizedTest { + assertJsonFormAndRestoredCustom( + UByteArraySerializer(), + ubyteArrayOf(1U, 220U), + "[1,220]" + ) { l, r -> l.contentEquals(r) } + + assertJsonFormAndRestoredCustom( + UShortArraySerializer(), + ushortArrayOf(1U, 65000U), + "[1,65000]" + ) { l, r -> l.contentEquals(r) } + + assertJsonFormAndRestoredCustom( + UIntArraySerializer(), + uintArrayOf(1U, 2147483657U), + "[1,2147483657]" + ) { l, r -> l.contentEquals(r) } + + assertJsonFormAndRestoredCustom( + ULongArraySerializer(), + ulongArrayOf(1U, 9223372036854775817U), + "[1,9223372036854775817]" + ) { l, r -> l.contentEquals(r) } + } + +// TODO uncomment when Kotlin 1.8.0 is released +// @OptIn(ExperimentalUnsignedTypes::class) +// fun testArrays() { +// val data = UnsignedArrays( +// ubyteArrayOf(1U, 220U), +// ushortArrayOf(1U, 65000U), +// uintArrayOf(1U, 2147483657U), +// ulongArrayOf(1U, 9223372036854775817U) +// ) +// val json = """{"uByte":[1,220],uShort:[1,65000],uInt:[1,2147483657],uLong:[1,9223372036854775817]}""" +// +// assertJsonFormAndRestored(UnsignedArrays.serializer(), data, json) +// } + } diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt index 59726d41f..ebcc3d07e 100644 --- a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTestBase.kt @@ -13,6 +13,7 @@ import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.test.* import kotlin.test.assertEquals import okio.* +import kotlin.test.assertTrue enum class JsonTestingMode { @@ -155,4 +156,21 @@ abstract class JsonTestBase { assertEquals(data, deserialized, "Failed with streaming = $jsonTestingMode") } } + /** + * Same as [assertStringFormAndRestored], but tests both json converters (streaming and tree) + * via [parametrizedTest]. Use custom checker for deserialized value. + */ + internal fun assertJsonFormAndRestoredCustom( + serializer: KSerializer, + data: T, + expected: String, + check: (T, T) -> Boolean + ) { + parametrizedTest { jsonTestingMode -> + val serialized = Json.encodeToString(serializer, data, jsonTestingMode) + assertEquals(expected, serialized, "Failed with streaming = $jsonTestingMode") + val deserialized: T = Json.decodeFromString(serializer, serialized, jsonTestingMode) + assertTrue("Failed with streaming = $jsonTestingMode\n\tsource value =$data\n\tdeserialized value=$deserialized") { check(data, deserialized) } + } + } }