-
Notifications
You must be signed in to change notification settings - Fork 8
Description
I have an immutable class where I want to apply the Json.Creator annotation (well, it's now JsonCreator from Jackson because you support that now; thanks for that!) and my JSON field names are all capitalized, while my constructor parameter names aren't. My example is https://github.com/Gold856/allwpilib/blob/f20d271fe3bad0bbf8aed6c8e338ce10a4b06a83/wpimath/src/main/java/edu/wpi/first/math/geometry/Quaternion.java, and this generates an adapter like so:
package edu.wpi.first.math.geometry;
import io.avaje.json.JsonAdapter;
import io.avaje.json.JsonReader;
import io.avaje.json.JsonWriter;
import io.avaje.json.PropertyNames;
import io.avaje.json.view.ViewBuilder;
import io.avaje.json.view.ViewBuilderAware;
import io.avaje.jsonb.AdapterFactory;
import io.avaje.jsonb.Jsonb;
import io.avaje.jsonb.Types;
import io.avaje.jsonb.spi.Generated;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
@Generated("io.avaje.jsonb.generator")
public final class QuaternionJsonAdapter implements JsonAdapter<Quaternion>, ViewBuilderAware {
// naming convention Match
// m_w [double] name:m_w ignoreSerialize ignoreDeserialize
// m_x [double] name:m_x ignoreSerialize ignoreDeserialize
// m_y [double] name:m_y ignoreSerialize ignoreDeserialize
// m_z [double] name:m_z ignoreSerialize ignoreDeserialize
// getW [double] name:W ignoreDeserialize
// getX [double] name:X ignoreDeserialize
// getY [double] name:Y ignoreDeserialize
// getZ [double] name:Z ignoreDeserialize
// w [double] name:W ignoreSerialize constructor
// x [double] name:X ignoreSerialize constructor
// y [double] name:Y ignoreSerialize constructor
// z [double] name:Z ignoreSerialize constructor
private final JsonAdapter<Double> pdoubleJsonAdapter;
private final PropertyNames names;
public QuaternionJsonAdapter(Jsonb jsonb) {
this.pdoubleJsonAdapter = jsonb.adapter(Double.TYPE);
this.names = jsonb.properties("m_w", "m_x", "m_y", "m_z", "W", "X", "Y", "Z");
}
@Override
public void toJson(JsonWriter writer, Quaternion _quaternion) {
writer.beginObject(names);
writer.name(4);
pdoubleJsonAdapter.toJson(writer, _quaternion.getW());
writer.name(5);
pdoubleJsonAdapter.toJson(writer, _quaternion.getX());
writer.name(6);
pdoubleJsonAdapter.toJson(writer, _quaternion.getY());
writer.name(7);
pdoubleJsonAdapter.toJson(writer, _quaternion.getZ());
writer.endObject();
}
@Override
public Quaternion fromJson(JsonReader reader) {
// variables to read json values into, constructor params don't need _set$ flags
double _val$w = 0;
double _val$x = 0;
double _val$y = 0;
double _val$z = 0;
// read json
reader.beginObject(names);
while (reader.hasNextField()) {
final String fieldName = reader.nextField();
switch (fieldName) {
case "m_w":
reader.skipValue();
break;
case "m_x":
reader.skipValue();
break;
case "m_y":
reader.skipValue();
break;
case "m_z":
reader.skipValue();
break;
case "W":
reader.skipValue();
break;
case "X":
reader.skipValue();
break;
case "Y":
reader.skipValue();
break;
case "Z":
reader.skipValue();
break;
default:
reader.unmappedField(fieldName);
reader.skipValue();
}
}
reader.endObject();
// direct return
return new Quaternion(_val$w, _val$x, _val$y, _val$z);
}
@SuppressWarnings("unchecked")
@Override
public boolean isViewBuilderAware() {
return true;
}
@Override
public ViewBuilderAware viewBuild() {
return this;
}
@Override
public void build(ViewBuilder builder, String name, MethodHandle handle) {
builder.beginObject(name, handle);
builder.add("W", pdoubleJsonAdapter, builder.method(Quaternion.class, "getW", double.class));
builder.add("X", pdoubleJsonAdapter, builder.method(Quaternion.class, "getX", double.class));
builder.add("Y", pdoubleJsonAdapter, builder.method(Quaternion.class, "getY", double.class));
builder.add("Z", pdoubleJsonAdapter, builder.method(Quaternion.class, "getZ", double.class));
builder.endObject();
}
}Attempts to work around this (without Jackson annotations) with some combo of well-placed Json.Alias annotations on the constructor parameters and Json.Property on the getters and Json.Ignore on the member variables failed. Even though I have a valid way of serializing, and I have a separate, valid way of deserializing, it seems like Avaje picks one or the other, and doesn't attempt to combine them. Optimally, this works like it does in Jackson, where I can make the serialization and deserialization be in different "paths" (constructor and getter, as compared to getter and setter.)
I understand this is kind of a weird request because JSON field names being different than the constructor parameter names is kinda weird, so if you want to reject this as won't fix, feel free.