001package com.mrivanplays.annotationconfig.yaml;
002
003import com.mrivanplays.annotationconfig.core.serialization.AnnotationAccessor;
004import com.mrivanplays.annotationconfig.core.serialization.DataObject;
005import com.mrivanplays.annotationconfig.core.serialization.FieldTypeSerializer;
006import com.mrivanplays.annotationconfig.core.serialization.SerializationContext;
007import com.mrivanplays.annotationconfig.core.serialization.SerializerRegistry;
008import java.util.LinkedHashMap;
009import java.util.Map;
010
011/**
012 * Represents a section object list serializer.
013 *
014 * @param <T> section object list object type
015 * @author MrIvanPlays
016 * @since v2.1.1
017 * @see SectionObjectList
018 */
019@SuppressWarnings({"unchecked", "rawtypes"})
020public final class SectionObjectListSerializer<T>
021    implements FieldTypeSerializer<SectionObjectList<T>> {
022
023  /** {@inheritDoc} */
024  @Override
025  public SectionObjectList<T> deserialize(
026      DataObject data,
027      SerializationContext<SectionObjectList<T>> context,
028      AnnotationAccessor annotations) {
029    SectionObjectList<T> def =
030        context
031            .getDefaultValue()
032            .orElseThrow(
033                () ->
034                    new IllegalArgumentException(
035                        "Illegal field to deserialize: null default SectionObjectList"));
036    Map<String, Object> map = data.getAsMap();
037    Map<String, T> deserialized = new LinkedHashMap<>();
038    SerializerRegistry serializerRegistry = SerializerRegistry.INSTANCE;
039    FieldTypeSerializer serializer =
040        serializerRegistry
041            .getSerializer(def.getObjectsType())
042            .orElse(serializerRegistry.getDefaultSerializer());
043    SerializationContext serializationContext =
044        SerializationContext.of(
045            def.getObjectsType(), def.getObjectsType(), context.getAnnotatedConfig());
046    for (Map.Entry<String, Object> entry : map.entrySet()) {
047      if (!(entry.getValue() instanceof Map)) {
048        throw new IllegalArgumentException("Illegal SectionObjectList inputted: " + data);
049      }
050      deserialized.put(
051          entry.getKey(),
052          (T)
053              serializer.deserialize(
054                  new DataObject(entry.getValue()),
055                  serializationContext,
056                  AnnotationAccessor.EMPTY));
057    }
058    return new SectionObjectList<>(def.getObjectsType(), deserialized);
059  }
060
061  /** {@inheritDoc} */
062  @Override
063  public DataObject serialize(
064      SectionObjectList<T> value,
065      SerializationContext<SectionObjectList<T>> context,
066      AnnotationAccessor annotations) {
067    DataObject ret = new DataObject();
068    SerializerRegistry serializerRegistry = SerializerRegistry.INSTANCE;
069    FieldTypeSerializer serializer =
070        serializerRegistry
071            .getSerializer(value.getObjectsType())
072            .orElse(serializerRegistry.getDefaultSerializer());
073    for (Map.Entry<String, T> entry : value) {
074      ret.putAll(
075          entry.getKey(),
076          serializer.serialize(
077              value.getObjectsType().cast(entry.getValue()),
078              SerializationContext.of(
079                  value.getObjectsType().cast(entry.getValue()),
080                  value.getObjectsType(),
081                  value.getObjectsType(),
082                  context.getAnnotatedConfig()),
083              AnnotationAccessor.EMPTY));
084    }
085    return ret;
086  }
087}