Skip to content

Commit b5cb36b

Browse files
committed
Add declaration order serialization order to Adaptable
This allows the config to use the unsorted field order (which should be the declaration order...) for serialization.
1 parent 8f7fd52 commit b5cb36b

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

src/main/java/ca/spottedleaf/yamlconfig/adapter/TypeAdapterRegistry.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ public Object serialize(final Object input, final Type type) {
129129
return ((TypeAdapter)adapter).serialize(this, input, type);
130130
}
131131

132-
public <T> TypeAdapter<T, Map<Object, Object>> makeAdapter(final Class<? extends T> clazz) throws Exception {
133-
final TypeAdapter<T, Map<Object, Object>> ret = new AutoTypeAdapter<>(this, clazz);
132+
public <T> TypeAdapter<T, Map<Object, Object>> makeAdapter(final Class<? extends T> clazz, final Adaptable adaptable) throws Exception {
133+
final TypeAdapter<T, Map<Object, Object>> ret = new AutoTypeAdapter<>(this, clazz, adaptable);
134134

135135
this.putAdapter(clazz, ret);
136136

@@ -161,10 +161,10 @@ private static final class AutoTypeAdapter<T> extends TypeAdapter<T, Map<Object,
161161
private final Constructor<? extends T> constructor;
162162
private final SerializableField[] fields;
163163

164-
public AutoTypeAdapter(final TypeAdapterRegistry registry, final Class<? extends T> clazz) throws Exception {
164+
public AutoTypeAdapter(final TypeAdapterRegistry registry, final Class<? extends T> clazz, final Adaptable adaptable) throws Exception {
165165
this.registry = registry;
166166
this.constructor = clazz.getConstructor();
167-
this.fields = findSerializableFields(registry, clazz);
167+
this.fields = findSerializableFields(registry, clazz, adaptable);
168168
}
169169

170170
private static TypeAdapter<?, ?> findOrMakeAdapter(final TypeAdapterRegistry registry, final Class<?> clazz) throws Exception {
@@ -175,7 +175,7 @@ public AutoTypeAdapter(final TypeAdapterRegistry registry, final Class<? extends
175175

176176
for (final Annotation annotation : clazz.getAnnotations()) {
177177
if (annotation instanceof Adaptable adaptable) {
178-
return registry.makeAdapter(clazz);
178+
return registry.makeAdapter(clazz, adaptable);
179179
}
180180
}
181181

@@ -191,7 +191,7 @@ private static void ensureGenericsInitialised(final TypeAdapterRegistry registry
191191

192192
for (final Annotation annotation : clazz.getAnnotations()) {
193193
if (annotation instanceof Adaptable adaptable) {
194-
registry.makeAdapter(clazz);
194+
registry.makeAdapter(clazz, adaptable);
195195
break;
196196
}
197197
}
@@ -231,7 +231,8 @@ private static record SerializableField(
231231
String serializedKey
232232
) {}
233233

234-
private static SerializableField[] findSerializableFields(final TypeAdapterRegistry registry, Class<?> clazz) throws Exception {
234+
private static SerializableField[] findSerializableFields(final TypeAdapterRegistry registry, Class<?> clazz,
235+
final Adaptable adaptable) throws Exception {
235236
final List<SerializableField> ret = new ArrayList<>();
236237
do {
237238
for (final Field field : clazz.getDeclaredFields()) {
@@ -268,9 +269,11 @@ private static SerializableField[] findSerializableFields(final TypeAdapterRegis
268269
}
269270
} while ((clazz = clazz.getSuperclass()) != Object.class);
270271

271-
ret.sort((final SerializableField c1, final SerializableField c2) -> {
272-
return c1.serializedKey.compareTo(c2.serializedKey);
273-
});
272+
if (!adaptable.useDeclarationOrder()) {
273+
ret.sort((final SerializableField c1, final SerializableField c2) -> {
274+
return c1.serializedKey.compareTo(c2.serializedKey);
275+
});
276+
}
274277

275278
return ret.toArray(new SerializableField[0]);
276279
}

src/main/java/ca/spottedleaf/yamlconfig/annotation/Adaptable.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,10 @@
1212
@Retention(RetentionPolicy.RUNTIME)
1313
@Target(ElementType.TYPE)
1414
public @interface Adaptable {
15+
16+
/**
17+
* Whether to use the field declaration order instead of sorting the fields by name.
18+
*/
19+
public boolean useDeclarationOrder() default false;
20+
1521
}

src/main/java/ca/spottedleaf/yamlconfig/config/YamlConfig.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ca.spottedleaf.yamlconfig.config;
22

33
import ca.spottedleaf.yamlconfig.adapter.TypeAdapterRegistry;
4+
import ca.spottedleaf.yamlconfig.annotation.Adaptable;
45
import org.yaml.snakeyaml.DumperOptions;
56
import org.yaml.snakeyaml.LoaderOptions;
67
import org.yaml.snakeyaml.Yaml;
@@ -19,6 +20,7 @@
1920
import java.io.InputStream;
2021
import java.io.InputStreamReader;
2122
import java.io.OutputStream;
23+
import java.lang.annotation.Annotation;
2224
import java.nio.charset.StandardCharsets;
2325
import java.nio.file.AtomicMoveNotSupportedException;
2426
import java.nio.file.Files;
@@ -43,10 +45,21 @@ public YamlConfig(final Class<? extends T> clazz, final T dfl) throws Exception
4345
}
4446

4547
public YamlConfig(final Class<? extends T> clazz, final T dfl, final TypeAdapterRegistry registry) throws Exception {
48+
Adaptable adaptable = null;
49+
for (final Annotation annotation : clazz.getAnnotations()) {
50+
if (annotation instanceof Adaptable a) {
51+
adaptable = a;
52+
break;
53+
}
54+
}
55+
if (adaptable == null) {
56+
throw new IllegalArgumentException("Class '" + clazz.getName() + "' must have the Adaptable annotation!");
57+
}
58+
4659
this.clazz = clazz;
4760
this.config = dfl;
4861
this.typeAdapters = registry;
49-
this.typeAdapters.makeAdapter(clazz);
62+
this.typeAdapters.makeAdapter(clazz, adaptable);
5063

5164
final LoaderOptions loaderOptions = new LoaderOptions();
5265
loaderOptions.setProcessComments(true);

0 commit comments

Comments
 (0)