-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Open
Labels
Description
Problem solved by the feature
Allow classes to be marked as serializable without needing another class as the serializer.
Is this similar to #594?
Feature description
It would work similarly to Java's Comparable
interface, so you wouldn't need a serializer in another class.
Currently, you need to either add a TypeAdapter as an external class through @JsonAdapter
or GsonBuilder
, but it would be much more convenient if the instance (of the object we're serializing) could serialize itself.
The implementation could look a little something like this (not the best code, triple nested anonymous classes my beloved) (I code in 4 spaces so the formatting may be a bit wonk):
public interface JsonSerializable {
TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
return !JsonSerializable.class.isAssignableFrom(type.getRawType()) ?
null : // return early if it isn't JsonSerializable
new TypeAdapter<>() { // SerializationDelegatingTypeAdapter? not sure what it does
private TypeAdapter<T> delegate;
private JsonSerializationContext context;
@Override
public void write(JsonWriter out, T value) throws IOException {
if (value instanceof JsonSerializable) // implicit null check
Streams.write(((JsonSerializable)value).serialize(type.getType(), context()), out);
else
delegate().write(out, value);
}
@Override
public T read(JsonReader in) throws IOException {
return delegate().read(in);
}
private TypeAdapter<T> delegate() { // taken from Excluder
TypeAdapter<T> d = delegate;
return d != null
? d
: (delegate = gson.getDelegateAdapter(JsonSerializable.FACTORY, type));
}
private JsonSerializationContext context() {
JsonSerializationContext jsc = this.context;
return jsc != null
? jsc
: (context = new JsonSerializationContext() { // expose GsonContextImpl?
@Override
public JsonElement serialize(Object src) {
return gson.toJsonTree(src);
}
@Override
public JsonElement serialize(Object src, Type typeOfSrc) {
return gson.toJsonTree(src, typeOfSrc);
}
});
}
};
}
};
JsonElement serialize(Type thisType, JsonSerializationContext context);
}
Alternatives / workarounds
Implement the serializer or TypeAdapter in another class.