Skip to content

Commit f0c89b7

Browse files
committed
Enhance BufDecoder and BufEncoder with custom serializer support and add tests for custom serialization
1 parent f048370 commit f0c89b7

File tree

3 files changed

+124
-21
lines changed

3 files changed

+124
-21
lines changed

src/main/kotlin/dev/slne/surf/bytebufserializer/internal/BufDecoder.kt

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,44 @@ class BufDecoder<B : ByteBuf>(
2121
return elementIndex++
2222
}
2323

24-
override fun decodeBoolean(): Boolean = buf.readBoolean()
25-
override fun decodeByte(): Byte = buf.readByte()
26-
override fun decodeShort(): Short = buf.readShort()
27-
override fun decodeInt(): Int = buf.readInt()
28-
override fun decodeLong(): Long = buf.readLong()
29-
override fun decodeFloat(): Float = buf.readFloat()
30-
override fun decodeDouble(): Double = buf.readDouble()
31-
override fun decodeChar(): Char = buf.readChar().toChar()
24+
override fun decodeBoolean(): Boolean = useCustomOr {
25+
buf.readBoolean()
26+
}
27+
28+
override fun decodeByte(): Byte = useCustomOr {
29+
buf.readByte()
30+
}
31+
32+
override fun decodeShort(): Short = useCustomOr {
33+
buf.readShort()
34+
}
35+
36+
override fun decodeInt(): Int = useCustomOr {
37+
buf.readInt()
38+
}
39+
40+
override fun decodeLong(): Long = useCustomOr {
41+
buf.readLong()
42+
}
43+
44+
override fun decodeFloat(): Float = useCustomOr {
45+
buf.readFloat()
46+
}
47+
48+
override fun decodeDouble(): Double = useCustomOr {
49+
buf.readDouble()
50+
}
51+
52+
override fun decodeChar(): Char = useCustomOr {
53+
buf.readChar().toChar()
54+
}
3255

3356

34-
override fun decodeString(): String {
57+
override fun decodeString(): String = useCustomOr {
3558
val length = buf.readInt()
3659
val bytes = ByteArray(length)
3760
buf.readBytes(bytes)
38-
return String(bytes, Charsets.UTF_8)
61+
String(bytes, Charsets.UTF_8)
3962
}
4063

4164
override fun decodeEnum(enumDescriptor: SerialDescriptor): Int {
@@ -52,8 +75,18 @@ class BufDecoder<B : ByteBuf>(
5275
}
5376

5477
override fun decodeCollectionSize(descriptor: SerialDescriptor): Int =
55-
buf.readInt().also { elementsCount = it }
78+
decodeInt().also { elementsCount = it }
5679

5780
override fun decodeSequentially(): Boolean = true
5881
override fun decodeNotNullMark(): Boolean = decodeBoolean()
82+
83+
private inline fun <reified T : Any> useCustomOr(fallback: () -> T): T {
84+
val serializer = serializersModule.getContextual(T::class)
85+
86+
return if (serializer != null) {
87+
decodeSerializableValue(serializer)
88+
} else {
89+
fallback()
90+
}
91+
}
5992
}

src/main/kotlin/dev/slne/surf/bytebufserializer/internal/BufEncoder.kt

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,39 @@ class BufEncoder<B : ByteBuf>(
1313
override val serializersModule: SerializersModule,
1414
private val encodeEnumWithOrdinal: Boolean,
1515
) : AbstractEncoder() {
16-
override fun encodeBoolean(value: Boolean) {
16+
override fun encodeBoolean(value: Boolean) = useCustomOr(value) {
1717
buf.writeBoolean(value)
1818
}
1919

20-
override fun encodeByte(value: Byte) {
20+
override fun encodeByte(value: Byte) = useCustomOr(value) {
2121
buf.writeByte(value.toInt())
2222
}
2323

24-
override fun encodeShort(value: Short) {
24+
override fun encodeShort(value: Short) = useCustomOr(value) {
2525
buf.writeShort(value.toInt())
2626
}
2727

28-
override fun encodeInt(value: Int) {
28+
override fun encodeInt(value: Int) = useCustomOr(value) {
2929
buf.writeInt(value)
3030
}
3131

32-
override fun encodeLong(value: Long) {
32+
override fun encodeLong(value: Long) = useCustomOr(value) {
3333
buf.writeLong(value)
3434
}
3535

36-
override fun encodeFloat(value: Float) {
36+
override fun encodeFloat(value: Float) = useCustomOr(value) {
3737
buf.writeFloat(value)
3838
}
3939

40-
override fun encodeDouble(value: Double) {
40+
override fun encodeDouble(value: Double) = useCustomOr(value) {
4141
buf.writeDouble(value)
4242
}
4343

44-
override fun encodeChar(value: Char) {
44+
override fun encodeChar(value: Char) = useCustomOr(value) {
4545
buf.writeChar(value.code)
4646
}
4747

48-
override fun encodeString(value: String) {
48+
override fun encodeString(value: String) = useCustomOr(value) {
4949
val bytes = value.toByteArray(Charsets.UTF_8)
5050
buf.writeInt(bytes.size)
5151
buf.writeBytes(bytes)
@@ -67,12 +67,21 @@ class BufEncoder<B : ByteBuf>(
6767
return this
6868
}
6969

70-
7170
override fun encodeNull() {
7271
encodeBoolean(false)
7372
}
7473

7574
override fun encodeNotNullMark() {
7675
encodeBoolean(true)
7776
}
77+
78+
private inline fun <reified T : Any> useCustomOr(value: T, fallback: () -> Unit) {
79+
val serializer = serializersModule.getContextual(T::class)
80+
81+
if (serializer != null) {
82+
encodeSerializableValue(serializer, value)
83+
} else {
84+
fallback()
85+
}
86+
}
7887
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package dev.slne.surf.bytebufserializer
2+
3+
import kotlinx.serialization.ExperimentalSerializationApi
4+
import kotlinx.serialization.KSerializer
5+
import kotlinx.serialization.Serializable
6+
import kotlinx.serialization.descriptors.PrimitiveKind
7+
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
8+
import kotlinx.serialization.descriptors.SerialDescriptor
9+
import kotlinx.serialization.encoding.Decoder
10+
import kotlinx.serialization.encoding.Encoder
11+
import kotlinx.serialization.modules.SerializersModule
12+
import kotlinx.serialization.modules.contextual
13+
import kotlin.test.Test
14+
import kotlin.test.assertFailsWith
15+
16+
class OverridingDefaultTypeSerializer {
17+
18+
private val bufFormat = Buf(SerializersModule {
19+
contextual(CustomStringSerializer)
20+
})
21+
22+
@Serializable
23+
data class Player(val name: String, val score: Int)
24+
25+
@Test
26+
fun `test encode using custom serializer`() {
27+
val player = Player("Alice", 42)
28+
29+
assertFailsWith<AssertionError> {
30+
val bytes = bufFormat.encodeToByteArray(player)
31+
println(bytes.joinToString())
32+
}
33+
}
34+
35+
@Test
36+
fun `test decode using custom serializer`() {
37+
val bytes = byteArrayOf(0, 0, 0, 5, 65, 108, 105, 99, 101, 0, 0, 0, 42)
38+
39+
assertFailsWith<AssertionError> {
40+
bufFormat.decodeFromByteArray<Player>(bytes)
41+
}
42+
}
43+
}
44+
45+
object CustomStringSerializer : KSerializer<String> {
46+
override val descriptor: SerialDescriptor =
47+
PrimitiveSerialDescriptor("CustomStringSerializer", PrimitiveKind.STRING)
48+
49+
@OptIn(ExperimentalSerializationApi::class)
50+
override fun serialize(
51+
encoder: Encoder,
52+
value: String
53+
) {
54+
throw AssertionError("This exception is expected")
55+
}
56+
57+
@OptIn(ExperimentalSerializationApi::class)
58+
override fun deserialize(decoder: Decoder): String {
59+
throw AssertionError("This exception is expected")
60+
}
61+
}

0 commit comments

Comments
 (0)