Daniele Andreoli
06/13/2022, 8:54 AM@Serializable(with = PaymentInfoSerializer::class)
data class PaymentInfo(
val id: PaymentId,
val amount: Float,
val paidAt: String?,
val productId: ProductId
)
The last field is a typealias for a Int type but it’s actually an evaluated one. The field is a field taken from an inner Json Object like this:
"product":{"id":74}
so the value is just the id field.
The entire json is like this one:
"id":22,"paidAt":null,"amount":720.0,"description":null,"product":{"id":74}
So my problem is that I can’t use simple deserilization with dataclass because I have to keep the code working but i can’t figure out how a map object is actually descripted inside a desirializer.
I’have written a descriptor like this but i’m not sure how ti could work as I have no way to tell it to take just the id field inside the map:
override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("PaymentInfo") {
element<PaymentId>("id")
element<Float>("amount")
element<String?>("paidAt", isOptional = true)
element<Map<String, Int>>("product")
}
At the end, i’ve to find a way to tell serilization to do something like this in GSON:
productId = jsonObject.get("product").asJsonObject.get("id").asInt
I've read the doc but I can't find some example that actually seems to fit and since I have to migrate a lot of this custom serializer I'm tring to start with the correct structure.
Is there someone who could help? ThanksLandry Norris
06/13/2022, 6:05 PM* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x8)
`frame #0: 0x000000010d014d10 MyFramework`kfun:kotlinx.serialization.json.Json#encodeToString(kotlinx.serialization.SerializationStrategy<0:0>;0:0){0§<kotlin.Any?>}kotlin.String [inlined] Composer at Composers.kt:13:9`
I’m using a standard
json.encodeToString(Model.serializer(), model)
using
private val json = Json {
isLenient = true
ignoreUnknownKeys = true
}
Everything works fine on Android, but fails on iOS. What should I be looking for?Chris Fillmore
06/14/2022, 4:52 PMminifyEnabled true
on the release build.
My question is, is it necessary to configure ProGuard for Kotlin serialization, if you always provide a serializer explicitly? So I mean, in every case I call it like this:
serializer.decodeFromString(MyData.serializer(), json)
// or
serializer.encodeToString(MyData.serializer(), myObj)
On observation, my program seems to work fine with obfuscation enabled, without any ProGuard configuration, if I am passing the serializer like this. This seems to contradict the docs:
The library works on Android, but, if you’re using ProGuard, you need to add rules to yourconfiguration to cover all classes that are serialized at runtime.<http://proguard-rules.pro|proguard-rules.pro>
Andrey Tabakov
06/15/2022, 11:51 AMis
is omitted while serialization?
I have data class
@Serializable
public data class Config(
val isVariable: String,
val anotherVariable: String
)
Config("omit", "value")
Output will be:
{anotherVariable:"value"}
P.S. isVariable should be boolean, I know, anyway it should be a String in my caseermac10k
06/21/2022, 10:30 AMribesg
06/24/2022, 4:04 PMclass Generic<T : Any>(
private val clazz: KClass<out T>,
) {
init {
require(clazz.hasAnnotation<Serializable>())
}
fun serialize(value: T): String {
val type = clazz.createType()
val serializer = Json.serializersModule.serializer(type)
return Json.encodeToString(serializer, value)
}
}
jessewilson
06/25/2022, 1:00 AMSerializersModule.getContextual(...)
? I’ve got a library that uses this behavior. I’m fine to ship a new release if this function’s signature changes, but I’m in deep trouble if the feature goes away altogether!jessewilson
06/25/2022, 1:06 AMJson.decodeFromDynamic
+ Json.encodeToDynamic
. On the JS engine I’m using (QuickJS) using these APIs has a massive performance advantage over doing encoding with Kotlin/JS and StringBuilder. (QuickJS doesn’t use ropes internally in its strings, so StringBuilder
is sloooow!)
Any ETA on stability here? Would y’all accept a pull request to remove @ExperimentalSerializationApi
on these?ribesg
06/29/2022, 11:22 AMjava.lang.VerifyError: class kotlinx.serialization.json.internal.StreamingJsonDecoder overrides final method kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object;
snowe
06/29/2022, 11:16 PMclass EitherSerializer<R>(
private val leftSerializer: KSerializer<PricingError>,
private val rightSerializer: KSerializer<R>,
) : KSerializer<Either<PricingError, R>> {
override val descriptor: SerialDescriptor
get() = rightSerializer.descriptor
private val errorJson = Json {
ignoreUnknownKeys = true
isLenient = true
encodeDefaults = true
}
override fun deserialize(decoder: Decoder): Either<PricingError, R> {
require(decoder is JsonDecoder) { "only works in JSON format" }
val element = Either.catch {
decoder.decodeJsonElement()
}.mapLeft { PricingError.SerializationError(it.localizedMessage) }
return when (element) {
is Either.Left -> element
is Either.Right -> {
try {
decoder.json.decodeFromJsonElement(rightSerializer, element.value).right()
} catch (_: SerializationException) {
errorJson.decodeFromJsonElement(leftSerializer, element.value).left() // fails here with error in thread
}
}
}
}
override fun serialize(encoder: Encoder, value: Either<PricingError, R>) {
TODO("Not yet implemented")
}
}
jw
06/30/2022, 2:15 PM@Serializer(forClass=)
but for an interface where the generated decoder throws UOE, or I could manually override decode and throw UOERahim Klaber
07/03/2022, 1:32 PMException in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Expected JsonPrimitive at self, found {"href":"<https://horizon.stellar.org/operations/122511124621283329>"}
. Could anyone take a look and tell me if I'm missing something obvious?. I'll put the code in the replies.ritesh
07/03/2022, 6:27 PMproto
schema for serialising or deserialising it.Yao-Wen Mei
07/06/2022, 9:40 PM@SerialInfo
annotation on Java annotations:
we have a Kotlin library which is depend on our Java library and use some of the Java annotations. I want to use some of the Java annotations during Kotlin serialization process. In order to do this, I have to 1) add @SerialInfo
on the Java annotations, and 2) define an inner class Impl
inside of my Java annotation for the Kotlin complier plugin. The working code is like below:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@SerialInfo //<--------------------------------------------------------- Add this line
@kotlin.annotation.Target(allowedTargets = AnnotationTarget.PROPERTY)
public @interface ServerTimestamp {
final class Impl implements ServerTimestamp { // <--------------------- Add this block
@Override
public Class<? extends Annotation> annotationType() {
return (Class<? extends Annotation>) ServerTimestamp.class;
}
}
}
My question is will the complier plugin always looking for the Impl
inner class in the future? How stable this mechanism is going to be? Thank you~Yao-Wen Mei
07/06/2022, 9:57 PM@Serializable (with = customJavaSerializer.class)
annotation on a Java class? (I want to have both the class itself and the custom serializer defined in Java, but use them in Kotlin)
I have tried define a Java class Hello
, and then define a custom serializer HelloSerializer
in Java. What is the field name or method name (like the Impl
in the previous annotation example) should I give, so that the complier plugin can get access to my custom java serializer with @Serializable
? Thank you very much.Martin Gaens
07/06/2022, 11:15 PMJsonContentPolymorphicSerializer
for the following class hierarchy? I want it to select the proper serializer by checking the value of the "ok" key in the JSON and if it's true, return a ApiResponse.Success
serializer and if false return the ApiResponse.Error
serializer.
@Serializable
internal sealed class ApiResponse {
@SerialName("ok") abstract val ok: Boolean
@Serializable
class Success<T>(
override val ok: Boolean,
@SerialName("result") val result: T
) : ApiResponse()
@Serializable
class Error(
override val ok: Boolean,
@SerialName("error_code") val errorCode: Int,
@SerialName("description") val description: String
) : ApiResponse()
}
Martin Gaens
07/08/2022, 10:44 PMMartin Gaens
07/09/2022, 12:19 AMBigDecimal
doesn't have a default serializer. Is the best thing to do creating a serializer for BigDecimal
?Adam S
07/11/2022, 9:55 AM{}
if a list is empty
I've written a custom serializer to handle this, and set contextual(List::class)
in the SerializersModule
, but I forgetting to add @Contextual
to all the list properties.
Is there a way to hardcode 'use my EmptyListEmptyObjectSerializer
for all `List<>`s' in a SerializersModule
?Stylianos Gakis
07/12/2022, 1:01 PMAction
with normal subclass class SomeAction : Action
and another interface subclass of type interface ServerAction : Action
which itself has implementations like class SpecificServerAction : ServerAction
.
I’ve been trying to think of how I need to setup my SerializersModule to make all of this work.
From what I understand since my interface is not sealed, I need to do something like this
polymorphic(Action::class) {
subclass(ServerAction::class, //??)
subclass(NavigationPushAction::class, NavigationPushAction.serializer())
subclass(NavigationPopAction::class, NavigationPopAction.serializer())
subclass(VoidAction::class, VoidAction.serializer())
}
but how do I do this for the ServerAction? Optimally I’d like to be able to define my ServerAction hierarchy the same way by providing all the subclasses, but I don’t see a way that the dsl allows me to do this?
I could probably do this by creating my own object ServerActionSerializer : KSerializer<ServerAction> {
and implementing it, but I’d rather not if possible? I like this subclass approach which can take care of it for me.
Am I missing something, any ideas maybe? Some part of the api I can be using that I am not?Yao-Wen Mei
07/12/2022, 7:30 PMFoo.java
, Is that possible I can to mark it @Serializable (with = ContextualSerializer<Foo>.class)
in side of Java, then use this Foo.java
in my Kotlin library as it is Serializable
, where inside of the Kotlin library, I define the SerializerModule
(build a contextual serializer for Foo.java class and also a list of other classes), and then pass the SerializerModule
to my custom ktxEncoder/ktxDecoder;
The key point for me to doing this is to avoid define a Kotlin serializer for Foo.java
in my Java library (we are trying to have at least Kotlin file in the Java lib as possible).
Also trying to avoid the @Contextual
annotation for my customers;darkmoon_uk
07/16/2022, 12:18 AMMap<String, JsonElement>
in the object? I've seen this feature exist in other frameworks e.g. Jackson. It can be used to afford a certain degree of future proofing to information-oriented API's e.g. the data could still be presented to the user and re-serialized as original.Ben Woodworth
07/16/2022, 3:11 PMBinaryFormat
and StringFormat
that could be extended, overriding some format-specific details (like instantiation?)
Otherwise I'm thinking of using the json tests as a starting point. I think my format is already well tested, I'm just worried I've got some small oversights. I'm also looking to implement support for polymorphism which I'm less comfortable with so knowing I've got all my bases covered would be reassuring :)vqrs
07/19/2022, 8:08 PMIgor Kolomiets
07/20/2022, 2:58 PMencodeU...
/ decodeU...
methods for unsigned types, so generic encodeSerializable…
/ decodeSerializable…
methods that require explicit serializer for the value have to be used when dealing with unsigned values?ribesg
07/20/2022, 3:24 PM> Task :linkPodDebugFrameworkIosArm64 FAILED
e: Could not find "org.jetbrains.kotlinx:kotlinx-serialization-core" in [/Users/ribesg/Projects/events, /Users/ribesg/.konan/klib, /Users/ribesg/.konan/kotlin-native-prebuilt-macos-aarch64-1.7.10/klib/common, /Users/ribesg/.konan/kotlin-native-prebuilt-macos-aarch64-1.7.10/klib/platform/ios_arm64]
If I try with kotlinx.serialization 1.4.0-RC I get this:
> Task :linkPodDebugFrameworkIosArm64 FAILED
e: Compilation failed: Expecting descriptor for kotlinx.serialization/MissingFieldException.<init>|399804788095754142[0]
* Source files:
* Compiler version info: Konan: 1.7.10 / Kotlin: 1.7.20
* Output kind: STATIC_CACHE
e: java.lang.IllegalStateException: Expecting descriptor for kotlinx.serialization/MissingFieldException.<init>|399804788095754142[0]
at org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker$KonanCachedLibraryModuleDeserializer.deserializeIrSymbol(KonanIrlinker.kt:635)
at org.jetbrains.kotlin.backend.common.serialization.FileDeserializationState$symbolDeserializer$3.invoke(IrFileDeserializer.kt:88)
at org.jetbrains.kotlin.backend.common.serialization.FileDeserializationState$symbolDeserializer$3.invoke(IrFileDeserializer.kt:77)
at org.jetbrains.kotlin.backend.common.serialization.IrSymbolDeserializer.deserializeIrSymbolData(IrSymbolDeserializer.kt:67)
Partho Paul
07/21/2022, 5:51 AM{"id1" : "1", "name" : "xyz"}
or {"id2" : "1", "name" : "xyz"}
and my DTO is data class MyObj(val id: String, val name: String)
. Is it possible to address such a use case using kotlinx serialization?Robert Jaros
07/21/2022, 8:23 AMVivek Modi
07/21/2022, 9:35 AMkotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project.
Vivek Modi
07/21/2022, 11:05 AM{
"TopicOne": [
{
"id": 1,
"seconds": 5.856,
"date": "21/10/2010"
},
.... // more data
],
"TopicTwo": [
{
"gameNumber": 6,
"name": "Heat",
"date": "21/11/2010"
},
..... // more data
],
"TopicThree": [
{
"id": 1,
"numberOfSets": 3,
"date": "21/11/2011",
},
....// more data
]
}
and see more in thread..Vivek Modi
07/21/2022, 11:05 AM{
"TopicOne": [
{
"id": 1,
"seconds": 5.856,
"date": "21/10/2010"
},
.... // more data
],
"TopicTwo": [
{
"gameNumber": 6,
"name": "Heat",
"date": "21/11/2010"
},
..... // more data
],
"TopicThree": [
{
"id": 1,
"numberOfSets": 3,
"date": "21/11/2011",
},
....// more data
]
}
and see more in thread..data class TopicResponse(
val topicOne: List<TopicOne>? = null,
val topicTwo: List<TopicTwo>? = null,
val topicThree: List<TopicThree>? = null
)
data class TopicOne(val id: Int? = null, val seconds: String? = null, val date: String? = null)
data class TopicTwo(val gameNumber: Int? = null, val name: String? = null, val date: String? = null)
data class TopicThree(val id: Int? = null, val numberOfSets: String? = null, val date: String? = null)
date
is common so created a base class
@Serializable
abstract class TopicBase {
abstract val date: String
}
@Serializable
class ChildTopicOne(override val date: String, private val id: Int, private val seconds: String?) : TopicBase() {
fun getString() :String {
return "Id $id has to complete the race in $seconds seconds"
}
}
@Serializable
class ChildTopicTwo(override val date: String, val gameNumber: Int, val name: String?) : TopicBase() {
fun getString() :String {
return "gameNumber $gameNumber has to complete the race in $name name"
}
}
@Serializable
class ChildTopicThree(override val date: String, val id: Int, val numberOfSets: String?) : TopicBase() {
fun getString() :String {
return "id $id has to complete the race in $numberOfSets numberOfSets"
}
}
response.topicOne?.forEach { topicOne ->
topicOne.date?.let {
val value: TopicBase = ChildTopicOne(it, topicOne.id, topicOne.seconds)
val data = Json.encodeToJsonElement(value)
Log.e("data", "${data}")
}
}
{
"type": "com.vivek.example.data.ChildTopicOne",
"date": "21/10/2010",
"seconds": "5.856",
"id": "1"
}
Expected Output
{
"type": "com.vivek.example.data.ChildTopicOne",
"getString": "Id 1 has to complete the race in 5.856 seconds"
}
Is it possible to get this type of output?