commonMain.io.ktor.util.converters.DataConversion.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ktor-utils-androidnativearm64 Show documentation
Show all versions of ktor-utils-androidnativearm64 Show documentation
Ktor is a framework for quickly creating web applications in Kotlin with minimal effort.
The newest version!
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
package io.ktor.util.converters
import io.ktor.util.*
import io.ktor.util.reflect.*
import io.ktor.utils.io.*
import kotlin.reflect.*
/**
* Data conversion plugin to serialize and deserialize types using [converters] registry
*/
public class DataConversion(configuration: Configuration) : ConversionService {
private val converters: Map, ConversionService> = configuration.converters.toMap()
override fun fromValues(values: List, type: TypeInfo): Any? {
if (values.isEmpty()) {
return null
}
val converter = converters[type.type] ?: DefaultConversionService
return converter.fromValues(values, type)
}
override fun toValues(value: Any?): List {
val type: KClass<*> = value?.let { it::class } ?: return listOf()
val converter = converters[type] ?: DefaultConversionService
return converter.toValues(value)
}
/**
* Data conversion service configuration
*/
@KtorDsl
public class Configuration {
internal val converters = mutableMapOf, ConversionService>()
/**
* Register a [convertor] for [type] type
*/
public fun convert(type: KClass<*>, convertor: ConversionService) {
converters[type] = convertor
}
/**
* Register and [configure] convertor for type [klass]
*/
@Suppress("UNCHECKED_CAST")
public fun convert(type: KType, configure: DelegatingConversionService.Configuration.() -> Unit) {
val klass = type.classifier as KClass
val configuration = DelegatingConversionService.Configuration(klass).apply(configure)
val service = DelegatingConversionService(
klass,
configuration.decoder,
configuration.encoder as ((Any?) -> List)?
)
convert(klass, service)
}
/**
* Register and [configure] convertor for reified type [T]
*/
public inline fun convert(
noinline configure: DelegatingConversionService.Configuration.() -> Unit
): Unit = convert(typeOf(), configure)
}
}
/**
* Implementation of [ConversionService] that delegates [fromValues] and [toValues] to [decoder] and [encoder]
*/
public class DelegatingConversionService(
private val klass: KClass<*>,
private val decoder: ((values: List) -> Any?)?,
private val encoder: ((value: Any?) -> List)?,
) : ConversionService {
override fun fromValues(values: List, type: TypeInfo): Any? {
val currentDecoder = decoder ?: throw IllegalStateException("Decoder was not specified for type '$klass'")
return currentDecoder(values)
}
override fun toValues(value: Any?): List {
val currentDecoder = encoder ?: throw IllegalStateException("Encoder was not specified for type '$klass'")
return currentDecoder(value)
}
/**
* Custom convertor builder to be used in [DataConversion.Configuration]
*/
public class Configuration @PublishedApi internal constructor(internal val klass: KClass) {
internal var decoder: ((values: List) -> T)? = null
internal var encoder: ((value: T) -> List)? = null
/**
* Configure decoder function. Only one decoder could be supplied
* @throws IllegalStateException
*/
public fun decode(converter: (values: List) -> T) {
if (decoder != null) throw IllegalStateException("Decoder has already been set for type '$klass'")
decoder = converter
}
/**
* Configure encoder function. Only one encoder could be supplied
* @throws IllegalStateException
*/
public fun encode(converter: (value: T) -> List) {
if (encoder != null) throw IllegalStateException("Encoder has already been set for type '$klass'")
encoder = converter
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy