Skip to content

Commit

Permalink
refactor!: remove kotlinx.serialization dependency
Browse files Browse the repository at this point in the history
Release-As: 0.3.0

Signed-off-by: Nicklas Lundin <[email protected]>
  • Loading branch information
nicklasl authored Apr 8, 2024
1 parent 700e16b commit 3145d6c
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 145 deletions.
2 changes: 0 additions & 2 deletions android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ plugins {
id("maven-publish")
id("signing")
id("org.jlleitschuh.gradle.ktlint")
kotlin("plugin.serialization") version "1.8.10"
}

val releaseVersion = project.extra["version"].toString()
Expand Down Expand Up @@ -98,7 +97,6 @@ publishing {

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
testImplementation("junit:junit:4.13.2")
testImplementation("org.mockito.kotlin:mockito-kotlin:5.1.0")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
Expand Down
59 changes: 1 addition & 58 deletions android/src/main/java/dev/openfeature/sdk/Value.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
package dev.openfeature.sdk

import android.annotation.SuppressLint
import dev.openfeature.sdk.exceptions.OpenFeatureError
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonContentPolymorphicSerializer
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.jsonObject
import java.text.SimpleDateFormat
import java.util.Date
import java.util.TimeZone

@Serializable(with = ValueSerializer::class)
sealed interface Value {

fun asString(): kotlin.String? = if (this is String) string else null
Expand All @@ -27,28 +11,20 @@ sealed interface Value {
fun asStructure(): Map<kotlin.String, Value>? = if (this is Structure) structure else null
fun isNull(): kotlin.Boolean = this is Null

@Serializable
data class String(val string: kotlin.String) : Value

@Serializable
data class Boolean(val boolean: kotlin.Boolean) : Value

@Serializable
data class Integer(val integer: Int) : Value

@Serializable
data class Double(val double: kotlin.Double) : Value

@Serializable
data class Date(@Serializable(DateSerializer::class) val date: java.util.Date) : Value
data class Date(val date: java.util.Date) : Value

@Serializable
data class Structure(val structure: Map<kotlin.String, Value>) : Value

@Serializable
data class List(val list: kotlin.collections.List<Value>) : Value

@Serializable
object Null : Value {
override fun equals(other: Any?): kotlin.Boolean {
return other is Null
Expand All @@ -58,37 +34,4 @@ sealed interface Value {
return javaClass.hashCode()
}
}
}

object ValueSerializer : JsonContentPolymorphicSerializer<Value>(Value::class) {
override fun selectDeserializer(element: JsonElement) = when (element.jsonObject.keys) {
emptySet<String>() -> Value.Null.serializer()
setOf("string") -> Value.String.serializer()
setOf("boolean") -> Value.Boolean.serializer()
setOf("integer") -> Value.Integer.serializer()
setOf("double") -> Value.Double.serializer()
setOf("date") -> Value.Date.serializer()
setOf("list") -> Value.List.serializer()
setOf("structure") -> Value.Structure.serializer()
else -> throw OpenFeatureError.ParseError("couldn't find deserialization key for Value")
}
}

@SuppressLint("SimpleDateFormat")
object DateSerializer : KSerializer<Date> {
private val dateFormatter =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").apply { timeZone = TimeZone.getTimeZone("UTC") }
private val fallbackDateFormatter =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").apply { timeZone = TimeZone.getTimeZone("UTC") }
override val descriptor = PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeString(dateFormatter.format(value))
override fun deserialize(decoder: Decoder): Date = with(decoder.decodeString()) {
try {
dateFormatter.parse(this)
?: throw IllegalArgumentException("unable to parse $this")
} catch (e: Exception) {
fallbackDateFormatter.parse(this)
?: throw IllegalArgumentException("unable to parse $this")
}
}
}
85 changes: 0 additions & 85 deletions android/src/test/java/dev/openfeature/sdk/ValueTests.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
package dev.openfeature.sdk

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
import org.junit.Assert
import org.junit.Test
import java.time.Instant
import java.util.Date

class ValueTests {

Expand Down Expand Up @@ -61,84 +56,4 @@ class ValueTests {
val value = Value.List(listOf())
Assert.assertEquals(listOf<Value>(), value.asList())
}

@Test
fun testEncodeDecode() {
val date = Date.from(Instant.parse("2023-03-01T14:01:46Z"))
val value = Value.Structure(
mapOf(
"null" to Value.Null,
"text" to Value.String("test"),
"bool" to Value.Boolean(true),
"int" to Value.Integer(3),
"double" to Value.Double(4.5),
"date" to Value.Date(date),
"list" to Value.List(listOf(Value.Boolean(false), Value.Integer(4))),
"structure" to Value.Structure(mapOf("int" to Value.Integer(5)))
)
)

val encodedValue = Json.encodeToJsonElement(value)
val decodedValue = Json.decodeFromJsonElement<Value>(encodedValue)

Assert.assertEquals(value, decodedValue)
}

@Test
fun testJsonDecode() {
val stringDateTime = "2023-03-01T14:01:46Z"
val json = "{" +
" \"structure\": {" +
" \"null\": {}," +
" \"text\": {" +
" \"string\": \"test\"" +
" }," +
" \"bool\": {" +
" \"boolean\": true" +
" }," +
" \"int\": {" +
" \"integer\": 3" +
" }," +
" \"double\": {" +
" \"double\": 4.5" +
" }," +
" \"date\": {" +
" \"date\": \"$stringDateTime\"" +
" }," +
" \"list\": {" +
" \"list\": [" +
" {" +
" \"boolean\": false" +
" }," +
" {" +
" \"integer\": 4" +
" }" +
" ]" +
" }," +
" \"structure\": {" +
" \"structure\": {" +
" \"int\": {" +
" \"integer\": 5" +
" }" +
" }" +
" }" +
" }" +
"}"

val expectedValue = Value.Structure(
mapOf(
"null" to Value.Null,
"text" to Value.String("test"),
"bool" to Value.Boolean(true),
"int" to Value.Integer(3),
"double" to Value.Double(4.5),
"date" to Value.Date(Date.from(Instant.parse(stringDateTime))),
"list" to Value.List(listOf(Value.Boolean(false), Value.Integer(4))),
"structure" to Value.Structure(mapOf("int" to Value.Integer(5)))
)
)

val decodedValue = Json.decodeFromString(Value.serializer(), json)
Assert.assertEquals(expectedValue, decodedValue)
}
}

0 comments on commit 3145d6c

Please sign in to comment.