aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/dev/isxander/yacl3/config/v2/api/serializer/GsonConfigSerializerBuilder.java
blob: 33003d72005a582f4f68b1a5a6171cbefc3d0db7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package dev.isxander.yacl3.config.v2.api.serializer;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import dev.isxander.yacl3.config.ConfigEntry;
import dev.isxander.yacl3.config.v2.api.ConfigClassHandler;
import dev.isxander.yacl3.config.v2.api.ConfigSerializer;
import dev.isxander.yacl3.config.v2.api.SerialEntry;
import dev.isxander.yacl3.config.v2.impl.serializer.GsonConfigSerializer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;

import java.awt.*;
import java.nio.file.Path;
import java.util.function.UnaryOperator;

/**
 * Uses GSON to serialize and deserialize config data from JSON to a file.
 * <p>
 * Only fields annotated with {@link dev.isxander.yacl3.config.v2.api.SerialEntry} are included in the JSON.
 * {@link Component}, {@link Style} and {@link Color} have default type adapters, so there is no need to provide them in your GSON instance.
 * GSON is automatically configured to format fields as {@code lower_camel_case}.
 * <p>
 * Optionally, this can also be written under JSON5 spec, allowing comments.
 *
 * @param <T> config data type
 */
public interface GsonConfigSerializerBuilder<T> {
    static <T> GsonConfigSerializerBuilder<T> create(ConfigClassHandler<T> config) {
        return new GsonConfigSerializer.Builder<>(config);
    }

    /**
     * Sets the file path to save and load the config from.
     */
    GsonConfigSerializerBuilder<T> setPath(Path path);

    /**
     * Sets the GSON instance to use. Overrides all YACL defaults such as:
     * <ul>
     *     <li>lower_camel_case field naming policy</li>
     *     <li>null serialization</li>
     *     <li>{@link Component}, {@link Style} and {@link Color} type adapters</li>
     * </ul>
     * Still respects the exclusion strategy to only serialize {@link ConfigEntry}
     * but these can be added to with setExclusionStrategies.
     *
     * @param gsonBuilder gson builder to use
     */
    GsonConfigSerializerBuilder<T> overrideGsonBuilder(GsonBuilder gsonBuilder);

    /**
     * Sets the GSON instance to use. Overrides all YACL defaults such as:
     * <ul>
     *     <li>lower_camel_case field naming policy</li>
     *     <li>null serialization</li>
     *     <li>{@link Component}, {@link Style} and {@link Color} type adapters</li>
     * </ul>
     * but these can be added to with setExclusionStrategies.
     *
     * @param gson gson instance to be converted to a builder
     */
    GsonConfigSerializerBuilder<T> overrideGsonBuilder(Gson gson);

    /**
     * Appends extra configuration to a GSON builder.
     * This is the intended way to add functionality to the GSON instance.
     * <p>
     * By default, YACL sets the GSON with the following options:
     * <ul>
     *     <li>lower_camel_case field naming policy</li>
     *     <li>null serialization</li>
     *     <li>{@link Component}, {@link Style} and {@link Color} type adapters</li>
     * </ul>
     * For example, if you wanted to revert YACL's lower_camel_case naming policy,
     * you could do the following:
     * <pre>
     * {@code
     * GsonConfigSerializerBuilder.create(config)
     *         .appendGsonBuilder(builder -> builder.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY))
     * }
     * </pre>
     *
     * @param gsonBuilder the function to apply to the builder
     */
    GsonConfigSerializerBuilder<T> appendGsonBuilder(UnaryOperator<GsonBuilder> gsonBuilder);

    /**
     * Writes the json under JSON5 spec, allowing the use of {@link SerialEntry#comment()}.
     * If enabling this option it's recommended to use the file extension {@code .json5}.
     *
     * @param json5 whether to write under JSON5 spec
     * @return this builder
     */
    GsonConfigSerializerBuilder<T> setJson5(boolean json5);

    ConfigSerializer<T> build();
}