Last active
December 17, 2021 08:34
-
-
Save samuel22gj/dbbe1df999baed6de8fdf074ffcb11aa to your computer and use it in GitHub Desktop.
SafeBooleanTypeAdapter for Kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BooleanTypeAdapterTest { | |
@Test | |
fun testBooleanTypeAdapter() { | |
val gson = GsonBuilder() | |
.registerTypeAdapter(Boolean::class.javaObjectType, BooleanObjectTypeAdapter()) | |
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanPrimitiveTypeAdapter()) | |
.create() | |
assertEquals(null, gson.fromJson("""{"isBoolean"=null}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=false}""", Foo::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"=true}""", Foo::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="true"}""", Foo::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="TrUe"}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="false"}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="FaLse"}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=""}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="0"}""", Foo::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="1"}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="2"}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=0}""", Foo::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"=1}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=2}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=[1,2]}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"={}}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"={"a"="b"}}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=null}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=false}""", Bar::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"=true}""", Bar::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="true"}""", Bar::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="TrUe"}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="false"}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="FaLse"}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=""}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="0"}""", Bar::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"="1"}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"="2"}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=0}""", Bar::class.java).isBoolean) | |
assertEquals(true, gson.fromJson("""{"isBoolean"=1}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=2}""", Bar::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"=[1,2]}""", Foo::class.java).isBoolean) | |
assertEquals(false, gson.fromJson("""{"isBoolean"={"a"="b"}}""", Foo::class.java).isBoolean) | |
} | |
data class Foo(var isBoolean: Boolean? = null) | |
data class Bar(var isBoolean: Boolean = false) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Module | |
class GsonModule { | |
@Singleton | |
@Provides | |
fun provideGson(): Gson { | |
return GsonBuilder() | |
.registerTypeAdapter(Boolean::class.javaObjectType, BooleanObjectTypeAdapter()) | |
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanPrimitiveTypeAdapter()) | |
.create() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private val TRUE_STRINGS: Array<String> = arrayOf("true", "1") | |
class BooleanObjectTypeAdapter : JsonDeserializer<Boolean?>, JsonSerializer<Boolean?> { | |
override fun serialize(src: Boolean?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { | |
return if (src == null) { | |
JsonNull.INSTANCE | |
} else { | |
JsonPrimitive(src) | |
} | |
} | |
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Boolean? { | |
if (json == null || json.isJsonNull) { | |
return null | |
} | |
return when { | |
json !is JsonPrimitive -> false | |
json.isBoolean -> json.asBoolean | |
json.isNumber -> json.asNumber.toInt() == 1 | |
json.isString -> TRUE_STRINGS.contains(json.asString.lowercase()) | |
else -> false | |
} | |
} | |
} | |
class BooleanPrimitiveTypeAdapter : JsonDeserializer<Boolean>, JsonSerializer<Boolean> { | |
override fun serialize(src: Boolean?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement { | |
return if (src == null) { | |
JsonPrimitive(false) | |
} else { | |
JsonPrimitive(src) | |
} | |
} | |
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Boolean { | |
if (json == null || json.isJsonNull) { | |
return false | |
} | |
return when { | |
json !is JsonPrimitive -> false | |
json.isBoolean -> json.asBoolean | |
json.isNumber -> json.asNumber.toInt() == 1 | |
json.isString -> TRUE_STRINGS.contains(json.asString.lowercase()) | |
else -> false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment