Skip to content

Commit

Permalink
feature(serializer-json, serializer-gson): Optionally emit type field…
Browse files Browse the repository at this point in the history
… for JSON serializers
  • Loading branch information
kezz committed Oct 30, 2024
1 parent 4967d24 commit 942682e
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,23 +70,31 @@
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.SELECTOR;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.SEPARATOR;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TEXT;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TRANSLATABLE;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TRANSLATE;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TRANSLATE_FALLBACK;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TRANSLATE_WITH;
import static net.kyori.adventure.text.serializer.json.JSONComponentConstants.TYPE;

final class ComponentSerializerImpl extends TypeAdapter<Component> {
static final Type COMPONENT_LIST_TYPE = new TypeToken<List<Component>>() {}.getType();
static final Type TRANSLATABLE_ARGUMENT_LIST_TYPE = new TypeToken<List<TranslationArgument>>() {}.getType();

static TypeAdapter<Component> create(final OptionState features, final Gson gson) {
return new ComponentSerializerImpl(features.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT), gson).nullSafe();
return new ComponentSerializerImpl(
features.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT),
features.value(JSONOptions.EMIT_COMPONENT_TYPE),
gson
).nullSafe();
}

private final boolean emitCompactTextComponent;
private final boolean emitComponentType;
private final Gson gson;

private ComponentSerializerImpl(final boolean emitCompactTextComponent, final Gson gson) {
private ComponentSerializerImpl(final boolean emitCompactTextComponent, final boolean emitComponentType, final Gson gson) {
this.emitCompactTextComponent = emitCompactTextComponent;
this.emitComponentType = emitComponentType;
this.gson = gson;
}

Expand Down Expand Up @@ -264,9 +272,11 @@ public void write(final JsonWriter out, final Component value) throws IOExceptio
}

if (value instanceof TextComponent) {
this.optionallyAddTypeName(out, TEXT);
out.name(TEXT);
out.value(((TextComponent) value).content());
} else if (value instanceof TranslatableComponent) {
this.optionallyAddTypeName(out, TRANSLATABLE);
final TranslatableComponent translatable = (TranslatableComponent) value;
out.name(TRANSLATE);
out.value(translatable.key());
Expand All @@ -280,6 +290,7 @@ public void write(final JsonWriter out, final Component value) throws IOExceptio
this.gson.toJson(translatable.arguments(), TRANSLATABLE_ARGUMENT_LIST_TYPE, out);
}
} else if (value instanceof ScoreComponent) {
this.optionallyAddTypeName(out, SCORE);
final ScoreComponent score = (ScoreComponent) value;
out.name(SCORE);
out.beginObject();
Expand All @@ -293,14 +304,17 @@ public void write(final JsonWriter out, final Component value) throws IOExceptio
}
out.endObject();
} else if (value instanceof SelectorComponent) {
this.optionallyAddTypeName(out, SELECTOR);
final SelectorComponent selector = (SelectorComponent) value;
out.name(SELECTOR);
out.value(selector.pattern());
this.serializeSeparator(out, selector.separator());
} else if (value instanceof KeybindComponent) {
this.optionallyAddTypeName(out, KEYBIND);
out.name(KEYBIND);
out.value(((KeybindComponent) value).keybind());
} else if (value instanceof NBTComponent) {
this.optionallyAddTypeName(out, NBT);
final NBTComponent<?, ?> nbt = (NBTComponent<?, ?>) value;
out.name(NBT);
out.value(nbt.nbtPath());
Expand All @@ -326,6 +340,13 @@ public void write(final JsonWriter out, final Component value) throws IOExceptio
out.endObject();
}

private void optionallyAddTypeName(final JsonWriter out, final String name) throws IOException {
if (this.emitComponentType) {
out.name(TYPE);
out.value(name);
}
}

private void serializeSeparator(final JsonWriter out, final @Nullable Component separator) throws IOException {
if (separator != null) {
out.name(SEPARATOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public final class JSONComponentConstants {
public static final String SHOW_ITEM_COUNT = "count";
public static final @Deprecated String SHOW_ITEM_TAG = "tag";
public static final String SHOW_ITEM_COMPONENTS = "components";
public static final String TYPE = "type";
public static final String TRANSLATABLE = "translatable";

private JSONComponentConstants() {
throw new IllegalStateException("Cannot instantiate");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private JSONOptions() {
* @sinceMinecraft 1.16
*/
public static final Option<Boolean> EMIT_RGB = Option.booleanOption(key("emit/rgb"), true);

/**
* Control how hover event values should be emitted.
*
Expand Down Expand Up @@ -83,6 +84,7 @@ private JSONOptions() {
* @since 4.15.0
*/
public static final Option<Boolean> VALIDATE_STRICT_EVENTS = Option.booleanOption(key("validate/strict_events"), true);

/**
* Whether to emit the default hover event item stack quantity of {@code 1}.
*
Expand All @@ -99,6 +101,18 @@ private JSONOptions() {
*/
public static final Option<ShowItemHoverDataMode> SHOW_ITEM_HOVER_DATA_MODE = Option.enumOption(key("emit/show_item_hover_data"), ShowItemHoverDataMode.class, ShowItemHoverDataMode.EMIT_EITHER);

/**
* Whether to emit the type of the component.
*
* <p>If {@link #EMIT_COMPACT_TEXT_COMPONENT} is `true`, the component type will not be emitted for compact text components.</p>
*
* <p>The client does not require the type field.</p>
*
* @since 4.18.0
* @sinceMinecraft 1.20.3
*/
public static final Option<Boolean> EMIT_COMPONENT_TYPE = Option.booleanOption(key("emit/component_type"), false);

/**
* Versioned by world data version.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonParseException;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -98,4 +99,66 @@ void testFailOnInvalidHoverEvents() {
});
}

@Test
void testComponentType() {
final JSONComponentSerializer serializer = JSONComponentSerializer
.builder()
.editOptions((builder) -> builder.value(JSONOptions.EMIT_COMPONENT_TYPE, true))
.build();

// Emit-compact text is on by default, so this should not include the type.
assertEquals("\"hi\"", serializer.serialize(Component.text("hi")));
this.testObject(
serializer,
Component.text("hi", NamedTextColor.RED),
object -> {
object.addProperty(JSONComponentConstants.TEXT, "hi");
object.addProperty(JSONComponentConstants.COLOR, NamedTextColor.RED.toString());
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.TEXT);
}
);
this.testObject(
serializer,
Component.translatable("hi"),
object -> {
object.addProperty(JSONComponentConstants.TRANSLATE, "hi");
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.TRANSLATABLE);
}
);
this.testObject(
serializer,
Component.score("me", "ow"),
object -> {
object.add(JSONComponentConstants.SCORE, object(inner -> {
inner.addProperty(JSONComponentConstants.SCORE_NAME, "me");
inner.addProperty(JSONComponentConstants.SCORE_OBJECTIVE, "ow");
}));
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.SCORE);
}
);
this.testObject(
serializer,
Component.selector("hi"),
object -> {
object.addProperty(JSONComponentConstants.SELECTOR, "hi");
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.SELECTOR);
}
);
this.testObject(
serializer,
Component.selector("hi"),
object -> {
object.addProperty(JSONComponentConstants.SELECTOR, "hi");
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.SELECTOR);
}
);
this.testObject(
serializer,
Component.keybind("hi"),
object -> {
object.addProperty(JSONComponentConstants.KEYBIND, "hi");
object.addProperty(JSONComponentConstants.TYPE, JSONComponentConstants.KEYBIND);
}
);
}
}

0 comments on commit 942682e

Please sign in to comment.