001package com.mrivanplays.annotationconfig.toml;
002
003import com.fasterxml.jackson.dataformat.toml.TomlMapper;
004import com.mrivanplays.annotationconfig.core.resolver.MultilineString;
005import com.mrivanplays.annotationconfig.core.resolver.ValueWriter;
006import com.mrivanplays.annotationconfig.core.resolver.settings.Settings;
007import java.io.IOException;
008import java.io.PrintWriter;
009import java.util.Collections;
010import java.util.LinkedList;
011import java.util.List;
012import java.util.Map;
013
014/**
015 * Represents the default toml value writer. Has a lot of stuff homebrew but the main dumping is
016 * done via jackson's {@link TomlMapper}.
017 *
018 * @author MrIvanPlays
019 * @since 2.1.0
020 */
021public final class TomlValueWriter implements ValueWriter {
022
023  private final TomlMapper defaultMapper;
024
025  public TomlValueWriter(TomlMapper defaultMapper) {
026    this.defaultMapper = defaultMapper;
027  }
028
029  @Override
030  public void write(
031      Map<String, Object> values,
032      Map<String, List<String>> fieldComments,
033      PrintWriter writer,
034      Settings settings)
035      throws IOException {
036    TomlMapper tomlMapper = settings.get(TomlConfig.MAPPER_KEY).orElse(defaultMapper);
037    for (Map.Entry<String, Object> entry : values.entrySet()) {
038      List<String> comments = getComments(entry.getKey(), fieldComments);
039      if (!comments.isEmpty()) {
040        for (String comment : comments) {
041          writer.println("# " + comment);
042        }
043      }
044      Object toWrite;
045      if (entry.getValue() instanceof MultilineString) {
046        toWrite = ((MultilineString) entry.getValue()).getString();
047      } else {
048        toWrite = entry.getValue();
049      }
050      writer.println(
051          tomlMapper.writeValueAsString(Collections.singletonMap(entry.getKey(), toWrite)));
052    }
053  }
054
055  private List<String> getComments(String key, Map<String, List<String>> toWriteComments) {
056    List<String> ret = new LinkedList<>();
057    if (toWriteComments.containsKey(key)) {
058      ret.addAll(toWriteComments.get(key));
059    } else {
060      for (Map.Entry<String, List<String>> entry : toWriteComments.entrySet()) {
061        if (entry.getKey().startsWith(key)) {
062          ret.addAll(entry.getValue());
063        }
064      }
065    }
066    return ret;
067  }
068}