package org.shedlang.compiler.util; import org.pcollections.Empty; import org.pcollections.PMap; import org.pcollections.PVector; import java.util.Optional; import java.util.stream.Stream; public class POrderedMap { public static POrderedMap empty() { return new POrderedMap<>(Empty.map(), Empty.vector()); } private final PMap map; private final PVector keys; private POrderedMap( PMap map, PVector keys ) { this.map = map; this.keys = keys; } public POrderedMap plus(K key, V value) { return new POrderedMap<>(map.plus(key, value), keys.plus(key)); } public POrderedMap plusAll(POrderedMap other) { var newMap = this; for (var otherKey : other.keys) { newMap = newMap.plus(otherKey, other.map.get(otherKey)); } return newMap; } public boolean containsKey(K key) { return map.containsKey(key); } public PVector keys() { return keys; } public Optional get(K key) { return Optional.ofNullable(map.get(key)); } public int size() { return keys.size(); } public Stream valueStream() { return keys.stream() .map(key -> map.get(key)); } @Override public boolean equals(Object other) { if (this == other) { return true; } if (other == null) { return false; } if (!(other instanceof POrderedMap otherMap)) { return false; } return map.equals(otherMap.map) && keys.equals(otherMap.keys); } @Override public int hashCode() { int result = map.hashCode(); result = 31 * result + keys.hashCode(); return result; } }