Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.31k stars 619 forks source link

Fallback nested json errors to default value #2693

Open amir1376 opened 3 months ago

amir1376 commented 3 months ago

Let's suppose I have this class

@Serializable
class Settings(
  val uiScale:Float=1f,
  val theme:String="dark",
)

I have serialized this class to a file which the result is

{
  "uiScale":1.0,
  "theme":"dark"
}

now some folk comes and change the json file content to this

{
  "uiScale":2.0, //from 1.0 to 2.0 (accpetable)
  "theme":1 //from "dark" to 1 (not acceptable and cause the whole serialization to fail because it must be string)
}

now when I try to deserialize my Settings class it will throw an exception

Is there any way when a key can't be deserialized use a default value and make the deserialization success ?

I need this result

{
  "uiScale":2.0,
  "theme":"dark" //because previous (1) is invalid for string type use default value that defined in data class
}

this is a simple example it could be very nested

sandwwraith commented 3 months ago

We don't have embedded functionality for this. The closest one is coerceInputValue, but it is for enums only. You can look at the json transformations (https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#json-transformations) to achieve result that you want.

amir1376 commented 3 months ago

But If I have to write custom serializer or transformer, I have to write it for all of my nested serializable classes is that right?

could I do this globaly (or at least on my parent class only) some how?

sandwwraith commented 2 months ago

Generally, yes, each class has its own serializer. However, you can move some common parts to a serializers' common ancestor

pdvrieze commented 2 months ago

Just make sure that each one has a different name (serialname of the typeis used as unique identifier for caching etc.)