ZupIT/nimbus

Serialization of states

Tiagoperes opened this issue · 0 comments

Today we have deserialization working well, but without also having serialization, we might run into some trouble. See the examples below:

In a component (using compose to exemplify):

@Deserializer
fun deserializeDate(data: AnyServerDrivenData): Date {
  val time = data.asLongOrNull()
  return time?.let { Date(it) } ?: Date()
}

@Composable
@AutoDeserialize
fun DatePicker(
  val value: Date,
  val onChange: (Date): Unit,
) {
  // ...
}

Above, we'd be able to deserialize a Long into a Date very easily, but what do we do when we call onChange with the new Date? Right now, if this is done, a Date object becomes the value of a state, which will 'cause a lot of problems, since a state must have a primitive value.

In order for this component to work today, the onChange must accept a Long and we must serialize the Date before calling onChange. This is very bad because we're tailoring the component for its usage with Nimbus, it wouldn't be natural for a native app to use Long instead of Date.

Date is just a simple example, this gets a lot worse for custom classes.

This problem also occurs with operations. Suppose you want to filter a list of a custom type. It's easy to deserialize the primitive types when entering the operation, but there's no automatic way to serialize it back before returning the result:

data class Note (
  id: Int,
  title: String,
  description: String,
  isDone: Boolean,
)

@AutoDeserialize
fun filterNotes(notes: List<Note>, isDone: Boolean) {
  return notes.filter { it.isDone == isDone }
}

The code above wouldn't work, because, internally, Nimbus only work with primitive types and Note is not primitive. The deserialization from the primitive type into Note is done automatically with the annotation @AutoDeserialize, but nothing is done with the return value, it should be serialized before returned.

We can serialize the values ourselves, but this is not great. If we can automatically deserialize, we should also be able to automatically serialize.

This problem also exists when setting a Global State.