Skip to content

Instantly share code, notes, and snippets.

@demodude4u
Last active May 4, 2018 00:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demodude4u/5a4952e388ef48d22bea81698383c1e9 to your computer and use it in GitHub Desktop.
Save demodude4u/5a4952e388ef48d22bea81698383c1e9 to your computer and use it in GitHub Desktop.
import java.awt.Point;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.json.JSONObject;
public class PreferencesConcept {
public static class PrefDef<T> {
private final String key;
private final Function<String,Optional<T>> parser;
private Optional<T> defaultValue = Optional.empty();
private Predicate<T> acceptCriteria = v -> true;
private Function<T,Object> writer = v -> v;
private Function<Object,T> reader = v -> (T)v;
private Function<T,String> display = v -> v.toString();
public PrefDef(String key, Function<String,Optional<T>> parser) {
this.key = key;
this.parser = parser;
}
PrefDef<T> defaultValue(T defaultValue) {
this.defaultValue = Optional.of(defaultValue);
return this;
}
PrefDef<T> acceptCriteria(Predicate<T> acceptCriteria) {
this.acceptCriteria = acceptCriteria;
return this;
}
<S> PrefDef<T> serialization(Function<T,S> writer, Function<S,T> reader) {
this.writer = (Function<T, Object>) writer;
this.reader = (Function<Object, T>) reader;
return this;
}
PrefDef<T> display(Function<T,String> display) {
this.display = display;
return this;
}
public boolean tryParseAndSetValue(JSONObject json, String valueString) {
Optional<T> valueOpt = parser.apply(valueString);
if (!valueOpt.isPresent()) {
return false;
}
T value = valueOpt.get();
if (!acceptCriteria.test(value)) {
return false;
}
json.put(key, writer.apply(valueOpt.get()));
return true;
}
public String displayValue(JSONObject json) {
return getValue(json).map(display).orElse("<Not Set>");
}
public Optional<T> getValue(JSONObject json) {
Optional<Object> serializedOpt = Optional.ofNullable(json.opt(key));
if (!serializedOpt.isPresent()) {
return defaultValue;
}
return Optional.of(reader.apply(serializedOpt.get()));
}
}
public static class Parsers {
public static final Function<String,Optional<Long>> LONG = str -> {
try {
return Optional.of(Long.parseLong(str));
} catch (NumberFormatException e) {
return Optional.empty();
}
};
public static final Function<String,Optional<Boolean>> BOOLEAN = str -> {
if (str.equalsIgnoreCase("true")) {
return Optional.of(true);
} else if (str.equalsIgnoreCase("false")) {
return Optional.of(false);
} else {
return Optional.empty();
}
};
public static final Function<String,Optional<Point>> POINT = str -> {
String[] split = str.split(",");
try {
int x = Integer.parseInt(split[0]);
int y = Integer.parseInt(split[1]);
return Optional.of(new Point(x,y));
} catch (Exception e) {
return Optional.empty();
}
};
}
public static class Demonstration {
//Pretend these are database calls...
private Function<String,JSONObject> databaseRead;
private BiConsumer<String,JSONObject> databaseWrite;
//Pretend these are helper functions...
private Predicate<Long> checkValidChannel;
private Function<Long,String> lookupChannelName;
//Pretend this is discord replying to the command author...
private Consumer<String> messageReply;
public List<PrefDef<?>> preferences = Arrays.asList(
new PrefDef<>("command_channel", Parsers.LONG)
.acceptCriteria(channel -> checkValidChannel.test(channel))
.display(channel -> lookupChannelName.apply(channel)),
new PrefDef<>("advanced_leaderboard", Parsers.BOOLEAN)
.defaultValue(true),
new PrefDef<>("enable_revoke_voting", Parsers.BOOLEAN)
.defaultValue(false),
new PrefDef<>("full_example", Parsers.POINT)
.defaultValue(new Point(0,0))
.acceptCriteria(point -> point.x > 0 && point.y > 0)
.display(point -> "["+point.x+","+point.y+"]")
.serialization(point -> {
JSONObject json = new JSONObject();
json.put("x", point.x);
json.put("y", point.y);
return json;
}, json -> new Point(json.getInt("x"), json.getInt("y")))
);
public void commandSetPreference(String serverID, String key, String valueString) {
JSONObject serverPrefs = databaseRead.apply(serverID);
Optional<PrefDef<?>> prefDefOpt = preferences.stream().filter(p -> p.key.equalsIgnoreCase(key)).findFirst();
if (!prefDefOpt.isPresent()) {
messageReply.accept("Error: Preference not found!");
return;
}
PrefDef<?> prefDef = prefDefOpt.get();
if (!prefDef.tryParseAndSetValue(serverPrefs, valueString)) {
messageReply.accept("Error: Value not accepted!");
return;
}
databaseWrite.accept(serverID, serverPrefs);
messageReply.accept("Server preference updated.");
}
public void commandGetPreference(String serverID, String key) {
JSONObject serverPrefs = databaseRead.apply(serverID);
Optional<PrefDef<?>> prefDefOpt = preferences.stream().filter(p -> p.key.equalsIgnoreCase(key)).findFirst();
if (!prefDefOpt.isPresent()) {
messageReply.accept("Error: Preference not found!");
return;
}
PrefDef<?> prefDef = prefDefOpt.get();
messageReply.accept(prefDef.key + " = " + prefDef.displayValue(serverPrefs));
}
public void commandListPreferences(String serverID) {
JSONObject serverPrefs = databaseRead.apply(serverID);
messageReply.accept(preferences.stream()
.map(p -> p.key + " = " + p.displayValue(serverPrefs))
.collect(Collectors.joining("\n")));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment