diff --git a/CHANGELOG.md b/CHANGELOG.md index 87ccad00..0d89307a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added - Wasm artifacts +- Add automatic MetaConverter for serializeable objects ### Changed diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaConverter.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaConverter.kt index 0dfb63d7..17774913 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaConverter.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/transformations/MetaConverter.kt @@ -1,7 +1,12 @@ package space.kscience.dataforge.meta.transformations +import kotlinx.serialization.KSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.encodeToJsonElement +import kotlinx.serialization.serializer import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.misc.DFExperimental import kotlin.reflect.KType import kotlin.reflect.typeOf @@ -141,19 +146,40 @@ public interface MetaConverter { public fun valueList( writer: (T) -> Value = { Value.of(it) }, reader: (Value) -> T, - ): MetaConverter> = - object : MetaConverter> { - override val type: KType = typeOf>() + ): MetaConverter> = object : MetaConverter> { + override val type: KType = typeOf>() - override val descriptor: MetaDescriptor = MetaDescriptor { - valueType(ValueType.LIST) - } - - override fun metaToObjectOrNull(meta: Meta): List? = meta.value?.list?.map(reader) - - override fun objectToMeta(obj: List): Meta = Meta(obj.map(writer).asValue()) + override val descriptor: MetaDescriptor = MetaDescriptor { + valueType(ValueType.LIST) } + override fun metaToObjectOrNull(meta: Meta): List? = meta.value?.list?.map(reader) + + override fun objectToMeta(obj: List): Meta = Meta(obj.map(writer).asValue()) + } + + /** + * Automatically generate [MetaConverter] for a class using its serializer and optional [descriptor] + */ + @DFExperimental + public inline fun serializable( + descriptor: MetaDescriptor? = null, + ): MetaConverter = object : MetaConverter { + override val type: KType = typeOf() + private val serializer: KSerializer = serializer() + + override fun metaToObjectOrNull(meta: Meta): T? { + val json = meta.toJson(descriptor) + return Json.decodeFromJsonElement(serializer, json) + } + + override fun objectToMeta(obj: T): Meta { + val json = Json.encodeToJsonElement(obj) + return json.toMeta(descriptor) + } + + } + } }