Skip to content

Commit 7262cdf

Browse files
committed
Add enum (de)serialisation support
1 parent 0bfcc24 commit 7262cdf

File tree

3 files changed

+71
-2
lines changed

3 files changed

+71
-2
lines changed

src/main/java/de/bluecolored/bluenbt/BlueNBT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public BlueNBT() {
7575
register(ArrayAdapterFactory.INSTANCE);
7676
register(PrimitiveSerializerFactory.INSTANCE);
7777
register(PrimitiveDeserializerFactory.INSTANCE);
78+
register(EnumAdapterFactory.INSTANCE);
7879
register(CollectionAdapterFactory.INSTANCE);
7980
register(MapAdapterFactory.INSTANCE);
8081
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package de.bluecolored.bluenbt.adapter;
2+
3+
import de.bluecolored.bluenbt.*;
4+
5+
import java.io.IOException;
6+
import java.util.Optional;
7+
8+
public class EnumAdapterFactory implements TypeAdapterFactory {
9+
10+
public static final EnumAdapterFactory INSTANCE = new EnumAdapterFactory();
11+
12+
@Override
13+
@SuppressWarnings({"unchecked", "rawtypes"})
14+
public <T> Optional<? extends TypeAdapter<T>> create(TypeToken<T> type, BlueNBT blueNBT) {
15+
Class<? super T> rawType = type.getRawType();
16+
17+
if (rawType.isEnum())
18+
return Optional.of((TypeAdapter<T>) new EnumAdapter(rawType));
19+
20+
return Optional.empty();
21+
}
22+
23+
static class EnumAdapter<E extends Enum<E>> implements TypeAdapter<E> {
24+
25+
private final Class<E> enumType;
26+
private final E[] universe;
27+
28+
public EnumAdapter(Class<E> enumType) {
29+
this.enumType = enumType;
30+
this.universe = enumType.getEnumConstants();
31+
}
32+
33+
@Override
34+
public void write(E value, NBTWriter writer) throws IOException {
35+
writer.value(value.name());
36+
}
37+
38+
@Override
39+
public TagType type() {
40+
return TagType.STRING;
41+
}
42+
43+
@Override
44+
public E read(NBTReader reader) throws IOException {
45+
try {
46+
return switch (reader.peek()) {
47+
case STRING -> Enum.valueOf(enumType, reader.nextString());
48+
case LONG -> universe[(int) reader.nextLong()];
49+
case INT -> universe[reader.nextInt()];
50+
case SHORT -> universe[reader.nextShort()];
51+
case BYTE -> universe[reader.nextByte()];
52+
default -> throw new IOException("Can't convert type %s into enum-type %s at %s".formatted(reader.peek(), enumType, reader.path()));
53+
};
54+
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
55+
throw new IOException("Invalid value for enum type %s at %s".formatted(enumType, reader.path()));
56+
}
57+
}
58+
59+
}
60+
61+
}

src/test/java/de/bluecolored/bluenbt/BlueNBTTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void testBlueNBT2() throws IOException {
7474

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

77-
assertEquals(1, playerData.gameMode);
77+
assertEquals(GameMode.CREATIVE, playerData.gameMode);
7878
assertEquals(-7630795211891119996L, playerData.worldUUIDLeast);
7979
assertEquals(-192242363273884439L, playerData.worldUUIDMost);
8080
assertEquals(3, playerData.position.length);
@@ -213,11 +213,18 @@ private enum TestEnum {
213213
ABC
214214
}
215215

216+
private enum GameMode {
217+
SURVIVAL,
218+
CREATIVE,
219+
ADVENTURE,
220+
SPECTATOR
221+
}
222+
216223
@SuppressWarnings({"unused", "MismatchedReadAndWriteOfArray"})
217224
private static class PlayerData {
218225

219226
@NBTName("playerGameType")
220-
private int gameMode;
227+
private GameMode gameMode;
221228

222229
@NBTName("Pos")
223230
private double[] position;

0 commit comments

Comments
 (0)