start 0.7.5 and add either serializer

This commit is contained in:
InsanusMokrassar 2021-11-02 12:43:59 +06:00
parent 3b1124a804
commit af132103a0
3 changed files with 88 additions and 3 deletions

View File

@ -1,5 +1,10 @@
# Changelog # Changelog
## 0.7.5
* `Common`:
* Type `Either` got its own serializer
## 0.7.4 ## 0.7.4
* `Common`: * `Common`:

View File

@ -1,5 +1,10 @@
package dev.inmo.micro_utils.common package dev.inmo.micro_utils.common
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
/** /**
* Realization of this interface will contains at least one not null - [t1] or [t2] * Realization of this interface will contains at least one not null - [t1] or [t2]
* *
@ -10,16 +15,90 @@ package dev.inmo.micro_utils.common
* @see Either.onFirst * @see Either.onFirst
* @see Either.onSecond * @see Either.onSecond
*/ */
@Serializable(EitherSerializer::class)
sealed interface Either<T1, T2> { sealed interface Either<T1, T2> {
val t1: T1? val t1: T1?
val t2: T2? val t2: T2?
companion object companion object {
fun <T1, T2> serializer(
t1Serializer: KSerializer<T1>,
t2Serializer: KSerializer<T2>,
): KSerializer<Either<T1, T2>> = EitherSerializer(t1Serializer, t2Serializer)
}
}
class EitherSerializer<T1, T2>(
t1Serializer: KSerializer<T1>,
t2Serializer: KSerializer<T2>,
) : KSerializer<Either<T1, T2>> {
@ExperimentalSerializationApi
@InternalSerializationApi
override val descriptor: SerialDescriptor = buildSerialDescriptor(
"TypedSerializer",
SerialKind.CONTEXTUAL
) {
element("type", String.serializer().descriptor)
element("value", ContextualSerializer(Either::class).descriptor)
}
private val t1EitherSerializer = EitherFirst.serializer(t1Serializer, t2Serializer)
private val t2EitherSerializer = EitherSecond.serializer(t1Serializer, t2Serializer)
@ExperimentalSerializationApi
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Either<T1, T2> {
return decoder.decodeStructure(descriptor) {
var type: String? = null
lateinit var result: Either<T1, T2>
while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> type = decodeStringElement(descriptor, 0)
1 -> {
result = when (type) {
"t1" -> decodeSerializableElement(
descriptor,
1,
t1EitherSerializer
)
"t2" -> decodeSerializableElement(
descriptor,
1,
t2EitherSerializer
)
else -> error("Unknown type of either: $type")
}
}
CompositeDecoder.DECODE_DONE -> break
else -> error("Unexpected index: $index")
}
}
result
}
}
@ExperimentalSerializationApi
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Either<T1, T2>) {
encoder.encodeStructure(descriptor) {
when (value) {
is EitherFirst -> {
encodeStringElement(descriptor, 0, "t1")
encodeSerializableElement(descriptor, 1, t1EitherSerializer, value)
}
is EitherSecond -> {
encodeStringElement(descriptor, 0, "t2")
encodeSerializableElement(descriptor, 1, t2EitherSerializer, value)
}
}
}
}
} }
/** /**
* This type [Either] will always have not nullable [t1] * This type [Either] will always have not nullable [t1]
*/ */
@Serializable
data class EitherFirst<T1, T2>( data class EitherFirst<T1, T2>(
override val t1: T1 override val t1: T1
) : Either<T1, T2> { ) : Either<T1, T2> {
@ -30,6 +109,7 @@ data class EitherFirst<T1, T2>(
/** /**
* This type [Either] will always have not nullable [t2] * This type [Either] will always have not nullable [t2]
*/ */
@Serializable
data class EitherSecond<T1, T2>( data class EitherSecond<T1, T2>(
override val t2: T2 override val t2: T2
) : Either<T1, T2> { ) : Either<T1, T2> {

View File

@ -45,5 +45,5 @@ dokka_version=1.5.31
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.7.4 version=0.7.5
android_code_version=78 android_code_version=79