Skip to content

Commit f9516df

Browse files
author
CoolLoong
committed
add createRecordFromNBT
1 parent 9d904a5 commit f9516df

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=3.0.6
1+
version=3.0.7

src/main/java/org/cloudburstmc/nbt/NbtUtils.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
import org.cloudburstmc.nbt.util.stream.NetworkDataOutputStream;
88

99
import java.io.*;
10+
import java.lang.reflect.Constructor;
1011
import java.lang.reflect.InvocationTargetException;
1112
import java.lang.reflect.Method;
13+
import java.lang.reflect.RecordComponent;
14+
import java.util.ArrayList;
1215
import java.util.Arrays;
16+
import java.util.List;
1317
import java.util.StringJoiner;
1418
import java.util.zip.GZIPInputStream;
1519
import java.util.zip.GZIPOutputStream;
@@ -169,4 +173,36 @@ public static NbtMap putRecordToNBT(Record record, NbtMap nbtMap) {
169173
}
170174
return builder.build();
171175
}
176+
177+
/**
178+
* Create record instance annotated with {@link NBT} from nbtMap
179+
*
180+
* @param <T> the type parameter
181+
* @param clazz the record class
182+
* @param nbtMap the nbt map
183+
* @return the record
184+
*/
185+
public static <T extends Record> T createRecordFromNBT(Class<T> clazz, NbtMap nbtMap) {
186+
NBT annotation = clazz.getAnnotation(NBT.class);
187+
if (annotation == null) {
188+
throw new IllegalArgumentException("This record does not use @NBT annotation!");
189+
}
190+
RecordComponent[] recordComponents = clazz.getRecordComponents();
191+
List<Object> params = new ArrayList<>(recordComponents.length);
192+
for (var c : recordComponents) {
193+
params.add(nbtMap.get(c.getName()));
194+
}
195+
try {
196+
Constructor<T> constructor = clazz.getDeclaredConstructor(Arrays.stream(recordComponents).map(RecordComponent::getType).toArray(Class[]::new));
197+
try {
198+
constructor.setAccessible(true);
199+
return constructor.newInstance(params.toArray());
200+
} finally {
201+
constructor.setAccessible(false);
202+
}
203+
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException |
204+
IllegalAccessException e) {
205+
throw new RuntimeException(e);
206+
}
207+
}
172208
}

src/main/java/org/cloudburstmc/nbt/annotation/NBT.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package org.cloudburstmc.nbt.annotation;
22

33

4+
import org.cloudburstmc.nbt.NbtMap;
5+
46
import java.lang.annotation.ElementType;
57
import java.lang.annotation.Retention;
68
import java.lang.annotation.RetentionPolicy;
79
import java.lang.annotation.Target;
810

11+
/**
12+
* {@link Record} marked with this annotation can be converted {@link org.cloudburstmc.nbt.NbtMap NBT} and create from it<p>
13+
* By using {@link org.cloudburstmc.nbt.NbtMap#fromRecord(Record) fromRecord} and {@link org.cloudburstmc.nbt.NbtUtils#createRecordFromNBT(Class, NbtMap) createRecordFromNBT}
14+
*/
915
@Target(value = {ElementType.TYPE})
1016
@Retention(RetentionPolicy.RUNTIME)
1117
public @interface NBT {

src/test/java/org/cloudburstmc/nbt/NbtTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@ record Data(int a, int b, int c) {
6868
{"a":1,"b":2,"c":3}""");
6969
}
7070

71+
@Test
72+
void testCreateRecordFromNBT() {
73+
NbtMap map = SNBTParser.parse(NbtType.COMPOUND, """
74+
{"a":1,"b":2,"c":3}""");
75+
@NBT
76+
record Data(int a, int b, int c) {
77+
}
78+
Data data = NbtUtils.createRecordFromNBT(Data.class, map);
79+
Assertions.assertEquals(new Data(1, 2, 3), data);
80+
}
81+
7182
@Test
7283
void testPutRecordToNBT() {
7384
@NBT

0 commit comments

Comments
 (0)