
dev.lukebemish.codecextras.structured.Keys Maven / Gradle / Ivy
package dev.lukebemish.codecextras.structured;
import com.mojang.datafixers.kinds.App;
import com.mojang.datafixers.kinds.K1;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
/**
* A collection of keys and their associated values. Each key is parameterized by a type extending {@code L}, and a
* value matching a given key will be of the type of {@code Mu} applied to the key's type.
* @param the type function mapping key type parameters to value types
* @param the bound on the key type parameters
*/
public final class Keys {
private final IdentityHashMap, App> keys;
private Keys(IdentityHashMap, App> keys) {
this.keys = keys;
}
/**
* {@return the value associated with a key, if present}
* @param key the key to search for
* @param the type parameter of the value associated with the key
*/
@SuppressWarnings("unchecked")
public Optional> get(Key key) {
return Optional.ofNullable((App) keys.get(key));
}
/**
* {@return a new instance with the same keys, with values whose type is the application of a different type function}
* @param converter converts {@code Mu} to {@code N} for each key's type parameter {@code T extends L}
* @param the type function associated with the new {@link Keys}
*/
public Keys map(Converter converter) {
var map = new IdentityHashMap, App>();
keys.forEach((key, value) -> map.put(key, converter.convert(value)));
return new Keys<>(map);
}
/**
* Effectively "lifts" values from {@code Mu} to {@code N}. Type parameters are bounded by {@code L}.
* @param
* @param
* @param
*/
public interface Converter {
/**
* {@return a single value, converted}
* @param input the value to convert
* @param the type parameter of the value to convert
*/
App convert(App input);
}
/**
* {@return a new key set builder}
* @param the type function mapping key type parameters to value types
* @param the bound on the key type parameters
*/
public static Builder builder() {
return new Builder<>();
}
/**
* {@return a new key set combining this set with another}
* Values in the other set will overwrite values in this set if they share a key.
* @param other the other key set to combine with this one
*/
public Keys join(Keys other) {
var map = new IdentityHashMap<>(this.keys);
map.putAll(other.keys);
return new Keys<>(map);
}
/**
* {@return a new key set with the single key-value pair provided added}
* @param key the key to add
* @param value the value to associate with the key
* @param the type parameter for the key
*/
public Keys with(Key key, App value) {
var map = new IdentityHashMap<>(this.keys);
map.put(key, value);
return new Keys<>(map);
}
public final static class Builder {
private final Map, App> keys = new IdentityHashMap<>();
public Builder add(Key key, App value) {
keys.put(key, value);
return this;
}
public Keys build() {
return new Keys<>(new IdentityHashMap<>(keys));
}
public Builder join(Keys other) {
keys.putAll(other.keys);
return this;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy