Skip to content

Commit

Permalink
Add enum (de)serialisation support
Browse files Browse the repository at this point in the history
  • Loading branch information
TBlueF committed Dec 22, 2024
1 parent 0bfcc24 commit 7262cdf
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/main/java/de/bluecolored/bluenbt/BlueNBT.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public BlueNBT() {
register(ArrayAdapterFactory.INSTANCE);
register(PrimitiveSerializerFactory.INSTANCE);
register(PrimitiveDeserializerFactory.INSTANCE);
register(EnumAdapterFactory.INSTANCE);
register(CollectionAdapterFactory.INSTANCE);
register(MapAdapterFactory.INSTANCE);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package de.bluecolored.bluenbt.adapter;

import de.bluecolored.bluenbt.*;

import java.io.IOException;
import java.util.Optional;

public class EnumAdapterFactory implements TypeAdapterFactory {

public static final EnumAdapterFactory INSTANCE = new EnumAdapterFactory();

@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> Optional<? extends TypeAdapter<T>> create(TypeToken<T> type, BlueNBT blueNBT) {
Class<? super T> rawType = type.getRawType();

if (rawType.isEnum())
return Optional.of((TypeAdapter<T>) new EnumAdapter(rawType));

return Optional.empty();
}

static class EnumAdapter<E extends Enum<E>> implements TypeAdapter<E> {

private final Class<E> enumType;
private final E[] universe;

public EnumAdapter(Class<E> enumType) {
this.enumType = enumType;
this.universe = enumType.getEnumConstants();
}

@Override
public void write(E value, NBTWriter writer) throws IOException {
writer.value(value.name());
}

@Override
public TagType type() {
return TagType.STRING;
}

@Override
public E read(NBTReader reader) throws IOException {
try {
return switch (reader.peek()) {
case STRING -> Enum.valueOf(enumType, reader.nextString());
case LONG -> universe[(int) reader.nextLong()];
case INT -> universe[reader.nextInt()];
case SHORT -> universe[reader.nextShort()];
case BYTE -> universe[reader.nextByte()];
default -> throw new IOException("Can't convert type %s into enum-type %s at %s".formatted(reader.peek(), enumType, reader.path()));
};
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new IOException("Invalid value for enum type %s at %s".formatted(enumType, reader.path()));
}
}

}

}
11 changes: 9 additions & 2 deletions src/test/java/de/bluecolored/bluenbt/BlueNBTTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void testBlueNBT2() throws IOException {

PlayerData playerData = blueNBT.read(new GZIPInputStream(in), PlayerData.class);

assertEquals(1, playerData.gameMode);
assertEquals(GameMode.CREATIVE, playerData.gameMode);
assertEquals(-7630795211891119996L, playerData.worldUUIDLeast);
assertEquals(-192242363273884439L, playerData.worldUUIDMost);
assertEquals(3, playerData.position.length);
Expand Down Expand Up @@ -213,11 +213,18 @@ private enum TestEnum {
ABC
}

private enum GameMode {
SURVIVAL,
CREATIVE,
ADVENTURE,
SPECTATOR
}

@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
private static class PlayerData {

@NBTName("playerGameType")
private int gameMode;
private GameMode gameMode;

@NBTName("Pos")
private double[] position;
Expand Down

0 comments on commit 7262cdf

Please sign in to comment.