Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlinx.jupyter.util.Serializers.kt Maven / Gradle / Ivy
package org.jetbrains.kotlinx.jupyter.util
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.serializer
import org.jetbrains.kotlinx.jupyter.api.ExactRendererTypeHandler
import org.jetbrains.kotlinx.jupyter.api.KotlinKernelVersion
import org.jetbrains.kotlinx.jupyter.api.ResultHandlerCodeExecution
import org.jetbrains.kotlinx.jupyter.api.libraries.CodeExecution
import org.jetbrains.kotlinx.jupyter.api.libraries.KernelRepository
import org.jetbrains.kotlinx.jupyter.api.libraries.ResourceFallbacksBundle
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
private val emptyJsonObject = JsonObject(mapOf())
@Suppress("UnusedReceiverParameter")
val Json.EMPTY get() = emptyJsonObject
abstract class PrimitiveStringPropertySerializer(
kClass: KClass,
private val prop: KProperty1,
private val ctr: (String) -> T,
) : KSerializer {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(kClass.qualifiedName!!, PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): T {
val p = decoder.decodeString()
return ctr(p)
}
override fun serialize(
encoder: Encoder,
value: T,
) {
encoder.encodeString(prop.get(value))
}
}
object CodeExecutionSerializer : PrimitiveStringPropertySerializer(
CodeExecution::class,
CodeExecution::code,
::CodeExecution,
)
object TypeHandlerCodeExecutionSerializer : PrimitiveStringPropertySerializer(
ResultHandlerCodeExecution::class,
ResultHandlerCodeExecution::code,
::ResultHandlerCodeExecution,
)
abstract class ListToMapSerializer(
private val utilSerializer: KSerializer>,
private val mapper: (K, V) -> T,
private val reverseMapper: (T) -> Pair,
) : KSerializer> {
override val descriptor: SerialDescriptor
get() = utilSerializer.descriptor
override fun deserialize(decoder: Decoder): List {
val tempMap = utilSerializer.deserialize(decoder)
return tempMap.map { (key, value) -> mapper(key, value) }
}
override fun serialize(
encoder: Encoder,
value: List,
) {
val tempMap = value.associate(reverseMapper)
utilSerializer.serialize(encoder, tempMap)
}
}
object RenderersSerializer : ListToMapSerializer(
serializer(),
::ExactRendererTypeHandler,
{ it.className to it.execution },
)
abstract class StringValueSerializer(
kClass: KClass,
private val serializer: (T) -> String = { it.toString() },
private val deserializer: (String) -> T,
) : KSerializer {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(kClass.qualifiedName!!, PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): T {
val str = decoder.decodeString()
return deserializer(str)
}
override fun serialize(
encoder: Encoder,
value: T,
) {
encoder.encodeString(serializer(value))
}
}
object KotlinKernelVersionSerializer : StringValueSerializer(
KotlinKernelVersion::class,
{ it.toString() },
{ str -> KotlinKernelVersion.from(str) ?: throw SerializationException("Wrong format of kotlin kernel version: $str") },
)
object ResourceBunchSerializer : KSerializer {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor(ResourceFallbacksBundle::class.qualifiedName!!, PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): ResourceFallbacksBundle {
return when (val obj = decoder.decodeSerializableValue(serializer())) {
is JsonArray -> {
ResourceFallbacksBundle(
obj.map {
Json.decodeFromJsonElement(it)
},
)
}
is JsonObject -> {
ResourceFallbacksBundle(
listOf(
Json.decodeFromJsonElement(obj),
),
)
}
else -> throw SerializationException("Wrong representation for resource location")
}
}
override fun serialize(
encoder: Encoder,
value: ResourceFallbacksBundle,
) {
encoder.encodeSerializableValue(serializer(), value.locations)
}
}
object PatternNameAcceptanceRuleSerializer : KSerializer {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor(PatternNameAcceptanceRule::class.qualifiedName!!, PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): PatternNameAcceptanceRule {
val rule = decoder.decodeString()
fun throwError(): Nothing = throw SerializationException("Wrong format of pattern rule: $rule")
val parts = rule.split(':').map { it.trim() }
val (sign, pattern) =
when (parts.size) {
1 -> "+" to parts[0]
2 -> parts[0] to parts[1]
else -> throwError()
}
val accepts =
when (sign) {
"+" -> true
"-" -> false
else -> throwError()
}
return PatternNameAcceptanceRule(accepts, pattern)
}
override fun serialize(
encoder: Encoder,
value: PatternNameAcceptanceRule,
) {
encoder.encodeString("${ if (value.acceptsFlag) '+' else '-' }:${value.pattern}")
}
}
object KernelRepositorySerializer : KSerializer {
override val descriptor: SerialDescriptor
get() = serializer().descriptor
override fun deserialize(decoder: Decoder): KernelRepository {
fun throwWrongFormat(reason: String? = null): Nothing =
throw SerializationException(
"Maven repository description has wrong format${reason?.let { ": $it" }.orEmpty()}",
)
val repository: KernelRepository =
when (val obj = decoder.decodeSerializableValue(serializer())) {
is JsonPrimitive -> {
if (!obj.isString) throwWrongFormat()
KernelRepository(obj.content)
}
is JsonObject -> {
val map = Json.decodeFromJsonElement(serializer>(), obj)
val path = map["path"] ?: map["url"] ?: throwWrongFormat("path is not specified")
val username = map["username"]
val password = map["password"]
KernelRepository(path, username, password)
}
else -> throwWrongFormat()
}
return repository
}
override fun serialize(
encoder: Encoder,
value: KernelRepository,
) {
val json =
if (value.username == null && value.password == null) {
JsonPrimitive(value.path)
} else {
buildJsonObject {
put("path", JsonPrimitive(value.path))
value.username?.let { put("username", JsonPrimitive(it)) }
value.password?.let { put("password", JsonPrimitive(it)) }
}
}
encoder.encodeSerializableValue(serializer(), json)
}
}