Skip to content

Instantly share code, notes, and snippets.

@Blad3Mak3r
Created March 16, 2022 17:54
Show Gist options
  • Save Blad3Mak3r/de7a734b4b40d4b42265269efefe9682 to your computer and use it in GitHub Desktop.
Save Blad3Mak3r/de7a734b4b40d4b42265269efefe9682 to your computer and use it in GitHub Desktop.
Redisson Codec for Kotlin JSON Serialization
@Serializable
data class Animal(
val id: Long,
val name: String
)
val client = Redisson.create(...)
val list = client.getList<Animal>("animals", AnimalsSerializationCodec)
object AnimalsSerializationCodec : BaseCodec() {
@OptIn(ExperimentalSerializationApi::class, InternalSerializationApi::class)
private val valueEncoder = Encoder {
val out = ByteBufAllocator.DEFAULT.buffer()
try {
val os = ByteBufOutputStream(out)
Json.encodeToStream(Animal.serializer(), it as Animal, os)
os.buffer()
} catch (e: IOException) {
out.release()
throw e
} catch (e: java.lang.Exception) {
out.release()
throw IOException(e)
}
}
@OptIn(ExperimentalSerializationApi::class)
private val valueDecoder = Decoder<Any> { buf, state ->
val content: Animal = Json.decodeFromStream(ByteBufInputStream(buf))
content
}
override fun getValueDecoder(): Decoder<Any> {
return valueDecoder
}
override fun getValueEncoder(): Encoder {
return valueEncoder
}
}
@alxgrk
Copy link

alxgrk commented Sep 28, 2022

Thank you for this gist!

A little more generic variation could look like this:

val STRING_CODEC = StringCodec()
class StringCodec() : KotlinxSerializationCodec<String>(serializer()) {
    // necessary to serve Redisson Codec requirements
    constructor(classLoader: ClassLoader, codec: StringCodec): this()
}
// ...

@OptIn(ExperimentalSerializationApi::class)
open class KotlinxSerializationCodec<T>(private val serializer: KSerializer<T>) : BaseCodec(), JsonCodec<T> {
    private val valueEncoder = Encoder {
        val out = ByteBufAllocator.DEFAULT.buffer()

        try {
            val os = ByteBufOutputStream(out)
            JsonSerializer.encodeToStream(serializer, it as T, os)
            os.buffer()
        } catch (e: IOException) {
            out.release()
            throw e
        } catch (e: Exception) {
            out.release()
            throw IOException(e)
        }
    }

    private val valueDecoder = Decoder<Any> { buf, _ ->
        val content: T = JsonSerializer.decodeFromStream(serializer, ByteBufInputStream(buf))
        content
    }

    override fun getValueDecoder(): Decoder<Any> = valueDecoder

    override fun getValueEncoder(): Encoder = valueEncoder
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment