Skip to content

Repository files navigation

Binkode — Bincode for Kotlin

Binkode is a Bincode binary serialization library for Kotlin/JVM.

It implements the Rust Bincode serialization format using kotlinx.serialization, enabling binary data exchange between Kotlin and Rust applications.

Project status

Binkode is currently in early development.

  • Some APIs may change between releases.
  • The Bincode API implementing kotlinx.serialization.BinaryFormat is considered stable.
  • Binkode aims to be fully compatible with the Rust bincode format and is tested against the reference implementation.

Installation

Available on Maven Central. Add it to your Gradle build:

repositories {
    mavenCentral()
}

dependencies {
    implementation("io.github.qvsorrow:binkode:0.1.0")
}

Bincode for Kotlin

Binkode provides a Kotlin implementation of the Bincode binary serialization format commonly used by Rust applications.

It integrates with kotlinx.serialization through BinaryFormat.

Usage

Binary encode / decode

import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import me.qvsorrow.binkode.Bincode

@Serializable
data class Point(val x: Int, val y: Int)

val bytes = Bincode.encodeToByteArray(Point(1, 2))
val point = Bincode.decodeFromByteArray<Point>(bytes)

Streaming with Okio

import me.qvsorrow.binkode.Bincode
import me.qvsorrow.binkode.decodeFromSource
import me.qvsorrow.binkode.encodeToSink
import okio.Buffer

val buffer = Buffer()
Bincode.encodeToSink(buffer, Point(1, 2))
val point = Bincode.decodeFromSource<Point>(buffer)

Custom configuration

import me.qvsorrow.binkode.Bincode
import me.qvsorrow.binkode.ByteEndian
import me.qvsorrow.binkode.IntEncoding

val bincode = Bincode {
    endian = ByteEndian.BigEndian
    intEncoding = IntEncoding.Fixed
}

Sealed types

Sealed subtypes require an explicit serial name built from SEALED_TAG:

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import me.qvsorrow.binkode.SEALED_TAG

@Serializable
sealed interface Shape {
    @SerialName("$SEALED_TAG;0")
    @Serializable
    data class Circle(val radius: Double) : Shape

    @SerialName("$SEALED_TAG;1")
    @Serializable
    data class Square(val side: Double) : Shape
}

From Bincode FAQ:

The encoding format is stable, provided the same configuration is used. This should ensure that later versions can still read data produced by a previous versions of the library if no major version change has occurred.

Bincode 1 and 2 are completely compatible if the same configuration is used.

Bincode is invariant over byte-order, making an exchange between different architectures possible. It is also rather space efficient, as it stores no metadata like struct field names in the output format and writes long streams of binary data without needing any potentially size-increasing encoding.

As a result, Bincode is suitable for storing data. Be aware that it does not implement any sort of data versioning scheme or file headers, as these features are outside the scope of this crate.

TODOs

  • @Serializable class
  • Unsigned types
  • List
  • Map
  • Nullable
  • Sealed (supported, but requires custom serial name)
  • value class
  • streaming support via Okio Source/Sink

About

Bincode binary serialization for Kotlin/JVM, built on kotlinx.serialization and Okio. Compatible with Rust bincode.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Contributors

Languages