Fallback value for unknown enum values
When deserializing enum values, it would be useful to specify a fallback value, in case a remote API introduces a new value for the enum.
Example:
enum class Color {
Red,
Green,
@FallbackEnumValue
Unknown,
}
data class Scarf(val colors: List<Color>)
Then, the following JSON:
{ "colors": ["Green", "Blue", "Red"] }
Would result in:
Scarf(listOf(Green, Unknown, Red))
Another use case would be an API returning an enum with many possible values, where the client only cares about a subset of them, and would like to consider all other as a single "Other" value.
This is supported in Jackson as @JsonEnumDefaultValue.
There was a similar issue #90, but it asked for the ability to use the default value as declared on the use site of the enum, which is different and not applicable to the above example.
I think an equivalent to coerceInputValues but as an annotation for use-site would also be nice and support null:
@Serializable
data class Something(
@CoerceInputValues val type: Type? = null
)
Could also be called @SerializeDefaultOnUnkown, or something else.
@LouisCAD What you are describing is more of a solution for the other issue I linked.
- I am looking for a declaration-side solution, so that you don't need to do it in 20 places if you use that enum in 20 places.
- It wouldn't work for collections, like my example shows.
- You might want a default value that's different from the fallback value, so coercing to default doesn't work for all cases. For example
val color: Color? = null, I wantnullif there is no color sent, butUnknownif there is a color, but the client doesn't support it. The API not sending a value is a normal valid case, where it sending an unknown value needs to be handled differently.
On the other hand, the issue you linked was closed without any such solution, nor reply from the concerns of putting it at the use-site.
There are basically 3 levels, and depending on the project's specifics, we might need a different level:
Json { … }config level (already implemented to some extent withcoerceInputValues, lacks connection to the affect symbols, no fine-grained control)- enum declaration level (what you are asking for), works everywhere the enum is used.
- use-site (what I also want as an option), works where the enum is used, if specified, and nowhere else.
I think we can have this issue be about those 2 latter levels, unless a maintainer asks us to split it, or decides to provide a solution for only one of the 2 missing levels (🥲), do you agree?
Hi @sandwwraith if someone opens a PR for this issue will that be accepted or in other words does serialisation team agree that this feature should be present in the Serialisation lib?
@Nohus did you find some workaround?
I think this should eventually be supported, yes. However, it requires careful design to determine whether we should also implement something similar to what @LouisCAD suggested: allowing this annotation on properties, not just enum entries, and whether it should be the same annotation. I do not see, for now, compelling use cases for property-level.
The problem with property level annotations for non-enum values (for defaults or fallbacks) is that annotations can only have limited value types. For enums it works if the value used is the serialName of the enum value to use. For others it is a challenge.