Gson - хорошая сериализация перечислений Kotlin со значением - PullRequest
0 голосов
/ 02 июня 2019

У меня есть перечисление со значениями

enum class Foo(val serverVal:Int) {
     BAR(1),
     BUG(2)
}

, который я хотел бы использовать с классом:

data class C1(val fooVal:Foo)

Я хочу иметь возможность сериализовать его с помощью кода, который выглядит как можно ближе к:

Gson().toJson(C1(Foo.BAR))

Это дало бы

{"fooVal":1}

Вместо конвертации по умолчанию, которая, конечно, {"fooVal":"BAR"}. Если бы это было строковое значение, я мог бы использовать @SerializedName, но не могу, потому что это Int, а не String.

Есть ли простой способ добавить что-то в Foo, чтобы показать Gson, как получать значение Int из записей Foo, а не их имя?

Примеры, которые я видел в Java, включают EnumAdapterFactory и TypeAdapter, которые довольно громоздки и не имеют смысла в симпатичном коде.

Я бы хотел получить решение, которое поддерживается в структуре данных.

enum class SomeEnum(val i:Int) {
   V1(1), V2(10), V3(5);

companion object {
   @SerializeMeLikeThis
   fun toJson() = i;

   @DeserializeMeLikeThat
   fun fromJson(v:Int) = values().find{it.i == v}?:whatever
}
}

Уродливый путь, но все еще заключенный в капсулу

data class C2(@SerializedName("foo") var serverFoo:Int) {
    // Becomes a nightmare with many params.
    constructor(f:Foo) : this(F.serverVal)
    var foo:Foo 
      get() = Foo.values().find{serverFoo == it.serverVal}?:whatever
      set(v) { serverFoo = v.serverVal }
}

Так его можно назвать

Gson().toJson(C2(BAR))

и

// Result: Foo.BAR
Gson().fromJson("""{"foo":"1"}""", C2::class.java).foo

Ну, вы можете жить на этом ... но это ...: - (

Любой хороший способ?

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...