package io.gitlab.jfronny.muscript.data.dynamic.additional; import io.gitlab.jfronny.commons.StringFormatter; import io.gitlab.jfronny.muscript.compiler.ExprWriter; import io.gitlab.jfronny.muscript.data.dynamic.*; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.*; /** * An enum represented as an OObject. * May also have a selected value with automatic conversions to a number (index) and string */ public record DEnum(Map> values, @Nullable DEnumEntry value) implements DObject { public DEnum(Map> values) { this(values, (DEnumEntry) null); } public DEnum(Map> values, @Nullable String value) { this(values, value == null ? null : new DEnumEntry(value, values.keySet().stream().toList().indexOf(value), true)); } public DEnum(List values, String value) { this(createMap(values, value), value == null ? null : new DEnumEntry(value, values.indexOf(value), true)); } public DEnum(List values) { this(values, null); } @Override public Map> getValue() { return values; } @Override public DList asList() { return DFinal.of(List.copyOf(values.values())); } @Override public DString asString() { return value != null ? value : DFinal.of(StringFormatter.toString(values)); } @Override public DNumber asNumber() { return value != null ? value.asNumber() : DObject.super.asNumber(); } @Override public void serialize(ExprWriter writer) throws IOException { writer.append("enum("); DObject.super.serialize(writer); if (value != null) { writer.append(", ").append(value.value); } writer.append(')'); } private static Map> createMap(List values, String value) { Map> result = new LinkedHashMap<>(); DEnumEntry v = new DEnumEntry(value, values.indexOf(value), true); result.put("value", v); for (int i = 0; i < values.size(); i++) { result.put(values.get(i), new DEnumEntry(values.get(i), i, values.get(i).equals(value))); } return Map.copyOf(result); } public record DEnumEntry(String value, int index, boolean selected) implements DString { @Override public String getValue() { return value; } @Override public DNumber asNumber() { return DFinal.of(index); } @Override public DBool asBool() { return DFinal.of(selected); } } }