001package com.mrivanplays.annotationconfig.toml;
002
003import com.fasterxml.jackson.dataformat.toml.TomlMapper;
004import com.fasterxml.jackson.dataformat.toml.TomlReadFeature;
005import com.mrivanplays.annotationconfig.core.resolver.ConfigResolver;
006import com.mrivanplays.annotationconfig.core.resolver.ValueWriter;
007import com.mrivanplays.annotationconfig.core.resolver.settings.ACDefaultSettings;
008import com.mrivanplays.annotationconfig.core.resolver.settings.Setting;
009import com.mrivanplays.annotationconfig.core.serialization.DataObject;
010import com.mrivanplays.annotationconfig.core.serialization.SerializerRegistry;
011import java.time.LocalDate;
012import java.time.LocalDateTime;
013import java.time.LocalTime;
014import java.time.OffsetDateTime;
015import java.util.Date;
016import java.util.LinkedHashMap;
017import java.util.Map;
018
019/**
020 * Represents configuration, utilising TOML.
021 *
022 * @since 1.0
023 * @author MrIvanPlays
024 */
025public final class TomlConfig {
026
027  private static final TomlMapper DEFAULT_TOML_MAPPER =
028      TomlMapper.builder().configure(TomlReadFeature.PARSE_JAVA_TIME, true).build();
029
030  /** Returns the {@link Setting} with which the mapper is referenced. */
031  public static final Setting<TomlMapper> MAPPER_KEY = Setting.of("mapper", TomlMapper.class);
032
033  private static ConfigResolver configResolver;
034
035  /**
036   * Returns the {@link ConfigResolver} instance for toml config.
037   *
038   * @return config resolver
039   */
040  public static ConfigResolver getConfigResolver() {
041    if (configResolver == null) {
042      generateConfigResolver();
043    }
044    return configResolver;
045  }
046
047  private static final ValueWriter TOML_VALUE_WRITER = new TomlValueWriter(DEFAULT_TOML_MAPPER);
048
049  private static void generateConfigResolver() {
050    SerializerRegistry registry = SerializerRegistry.INSTANCE;
051    if (!registry.hasSerializer(OffsetDateTime.class)) {
052      registry.registerSimpleSerializer(
053          OffsetDateTime.class,
054          data -> OffsetDateTime.parse(data.getAsString()),
055          value -> new DataObject(value.toString()));
056    }
057    if (!registry.hasSerializer(LocalDateTime.class)) {
058      registry.registerSimpleSerializer(
059          LocalDateTime.class,
060          data -> LocalDateTime.parse(data.getAsString()),
061          value -> new DataObject(value.toString()));
062    }
063    if (!registry.hasSerializer(LocalDate.class)) {
064      registry.registerSimpleSerializer(
065          LocalDate.class,
066          data -> LocalDate.parse(data.getAsString()),
067          value -> new DataObject(value.toString()));
068    }
069    if (!registry.hasSerializer(LocalTime.class)) {
070      registry.registerSimpleSerializer(
071          LocalTime.class,
072          data -> LocalTime.parse(data.getAsString()),
073          value -> new DataObject(value.toString()));
074    }
075    configResolver =
076        ConfigResolver.newBuilder()
077            .withSetting(MAPPER_KEY, DEFAULT_TOML_MAPPER)
078            .withSetting(ACDefaultSettings.GENERATE_NEW_OPTIONS, false)
079            .withSetting(ACDefaultSettings.SHOULD_REVERSE_FIELDS, true)
080            .withValueWriter(TOML_VALUE_WRITER)
081            .withCommentPrefix("# ")
082            .withFileExtension(".toml")
083            .withValueReader(
084                (reader, settings) ->
085                    (Map<String, Object>)
086                        settings
087                            .get(MAPPER_KEY)
088                            .orElse(DEFAULT_TOML_MAPPER)
089                            .reader()
090                            .readValue(reader, LinkedHashMap.class))
091            .build();
092  }
093}