Skip to content

Commit

Permalink
added message serializer extension
Browse files Browse the repository at this point in the history
  • Loading branch information
CharlieTap committed Feb 12, 2023
1 parent 1285cb1 commit 96e5654
Show file tree
Hide file tree
Showing 60 changed files with 181 additions and 8 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ You'll need both Synk runtime and the delightful metastore artifacts to get star
```kotlin
dependencies {
implementation("com.github.charlietap.synk:delight-metastore:xxx")
implementation("com.github.charlietap.synk:runtime:xxx")
implementation("com.github.charlietap.synk:synk:xxx")
}
```
Alternatively if you're working with a KMP project you can pull the specialised dependencies for the different targets:

```kotlin
dependencies {
implementation("com.github.charlietap.synk:runtime-android:xxx")
implementation("com.github.charlietap.synk:synk-android:xxx")
//or
implementation("com.github.charlietap.synk:runtime-jvm:xxx")
implementation("com.github.charlietap.synk:synk-jvm:xxx")
}
```

Expand Down
2 changes: 1 addition & 1 deletion delight-metastore/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation(projects.runtime)
// implementation(projects.synk)
implementation(projects.concurrentMap)
implementation(libs.murmurhash)
implementation(libs.androidx.collections.kmp)
Expand Down
42 changes: 42 additions & 0 deletions extension/kotlin-serialization/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

@Suppress("DSL_SCOPE_VIOLATION")
plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlinter)
id("maven-publish")
}
group = "com.tap.synk.extension"
version = libs.versions.version.name.get()

kotlin {

jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(libs.versions.java.build.version.get().toInt()))
vendor.set(JvmVendorSpec.ADOPTIUM)
}

targets {
jvm()
}

sourceSets {
val commonMain by getting {
dependencies {
implementation(projects.synk)
implementation(libs.kotlinx.serialization)
}
}

val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
}
}

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.jvmTarget = libs.versions.java.bytecode.version.get()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.tap.synk.extension

import com.tap.synk.meta.Meta
import com.tap.synk.relay.Message
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.decodeStructure
import kotlinx.serialization.encoding.encodeStructure

class MessageSerializer<T>(
private val innerSerializer: KSerializer<T>
) : KSerializer<Message<T>> {

override val descriptor: SerialDescriptor = buildClassSerialDescriptor("message") {
element("crdt", innerSerializer.descriptor)
element("meta", MetaSerializer.descriptor)
}
override fun serialize(encoder: Encoder, value: Message<T>) = encoder.encodeStructure(descriptor) {
encodeSerializableElement(descriptor, 0, innerSerializer, value.crdt)
encodeSerializableElement(descriptor, 1, MetaSerializer, value.meta)
}

override fun deserialize(decoder: Decoder): Message<T> = decoder.decodeStructure(descriptor) {
var crdt : T? = null
var meta : Meta? = null
while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> crdt = decodeSerializableElement(descriptor, 0, innerSerializer)
1 -> meta = decodeSerializableElement(descriptor, 1, MetaSerializer)
CompositeDecoder.DECODE_DONE -> break
else -> error("Unexpected index: $index")
}
}
Message(crdt!!, meta!!)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.tap.synk.extension

import com.tap.synk.meta.Meta
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.decodeStructure
import kotlinx.serialization.encoding.encodeStructure

object MetaSerializer : KSerializer<Meta> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("meta") {
element<String>("clazz")
element<Map<String, String>>("timestamp_meta")
}

override fun serialize(encoder: Encoder, value: Meta) = encoder.encodeStructure(descriptor) {
encodeStringElement(descriptor, 0, value.clazz)
encodeSerializableElement(descriptor, 1, MapSerializer(String.serializer(), String.serializer()), value.timestampMeta)
}

override fun deserialize(decoder: Decoder): Meta = decoder.decodeStructure(descriptor) {
var clazz = ""
var timestampMeta = emptyMap<String, String>()
while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> clazz = decodeStringElement(descriptor, 0)
1 -> timestampMeta = decodeSerializableElement(descriptor, 1, MapSerializer(String.serializer(), String.serializer()))
CompositeDecoder.DECODE_DONE -> break
else -> error("Unexpected index: $index")
}
}
Meta(clazz, timestampMeta)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.tap.synk.extension

import kotlinx.serialization.Serializable

@Serializable
data class Foo(val name: String, val age: Int)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.tap.synk.extension

import com.tap.synk.meta.Meta
import com.tap.synk.relay.Message
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlinx.serialization.json.Json

class MessageSerializerTest {

@Test
fun `serializer correctly serializes and deserializes message`() {
val foo = Foo("bar", 30)
val meta = Meta("foo", mapOf("foo" to "bar"))
val message = Message(foo, meta)

val serializer = MessageSerializer(Foo.serializer())

val json = Json.encodeToString(serializer, message)
val result = Json.decodeFromString(serializer, json)

assertEquals(message, result)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.tap.synk.extension


import com.tap.synk.meta.Meta
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlinx.serialization.json.Json

class MetaSerializerTest {

@Test
fun `serializer correctly serializes and deserializes meta`() {
val meta = Meta("test", mapOf("foo" to "bar"))
val json = Json.encodeToString(MetaSerializer, meta)
val result = Json.decodeFromString(MetaSerializer, json)

assertEquals(meta, result)
}
}
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ java-build-version = "19"
java-bytecode-version = "11"
target-sdk = "32"
min-sdk = "24"
version-name = "0.26"
version-name = "0.30"

android-build-tools-plugin = "7.4.0-beta02"

Expand Down Expand Up @@ -48,7 +48,7 @@ kotlinter = "3.11.1"
kotlinx-atomic-fu = "0.18.5"
kotlinx-coroutines = "1.6.1"
kotlinx-datetime = "0.3.3"
kotlinx-serialization = "1.3.3"
kotlinx-serialization = "1.5.0-RC"

ktor = "2.0.3"

Expand Down
5 changes: 3 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ dependencyResolutionManagement {
//}

include(":concurrent-map")
include(":runtime")
include(":synk")
include(":extension:kotlin-serialization")
include(":delight-metastore")

rootProject.name = "synk"
rootProject.name = "synk-multiplatform"

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
File renamed without changes.
File renamed without changes.

0 comments on commit 96e5654

Please sign in to comment.