How to deserialize JSON enums in case insensitive way using Moshi library?

39 views Asked by At

The sample source JSON object is defined as:

{
  "source": "WIFI"
}

However, the value can be lowercase and when it does, I get following error.

Exception in thread "main" com.squareup.moshi.JsonDataException: 
Expected one of [WIFI, CELL, GPS] but was 'wifi' at path $.locations[1].source

There there known annotation or out of box solution to convert lowercase to upper case enum?

I am looking at the https://github.com/square/moshi/blob/master/moshi-adapters/src/main/java/com/squareup/moshi/adapters/EnumJsonAdapter.kt to see if that can be modified for this.

1

There are 1 answers

0
Hossain Khan On BEST ANSWER

I was able to modify the EnumJsonAdapter to handle lower or upper case JSON coming from the response by some modification.

Here is snippet of it

// From fun fromJson(reader: JsonReader): T? 

if(useCaseInsensitiveName) {
  val name = reader.nextString()
  // Find if `name` is in the `nameStrings` array in case-insensitive manner
  val itemIndex = nameStrings.indexOfFirst { it.equals(name, ignoreCase = true) }
  if (itemIndex != -1) {
    return constants[itemIndex]
  }
  return fallbackValue
} else {
  reader.skipValue()
  return fallbackValue
}

That seems to work well from both ways UPPER_CASE / lower_case \ MIXED_case


Here is the modified file with the full change.

Usage after modification

Moshi.Builder()
  .add(
    LocationRecordSource::class.java,
        EnumCustomJsonAdapter.create(LocationRecordSource::class.java).withUnknownFallback(
          fallbackValue = LocationRecordSource.UNKNOWN,
          useCaseInsensitiveName = true,
        ),
      )
  .build()