make either not bad

This commit is contained in:
dfsek
2025-12-28 22:27:08 -07:00
parent b851b2f881
commit 4f672dfb7b
3 changed files with 103 additions and 61 deletions

View File

@@ -21,10 +21,7 @@ public class ShortcutBlockStateFallbackAddon implements AddonInitializer {
platform.getEventManager() platform.getEventManager()
.getHandler(FunctionalEventHandler.class) .getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class) .register(addon, ConfigPackPreLoadEvent.class)
.then(event -> event.getPack()
.registerShortcut(Palette.class, "FALLBACK",
(configLoader, input, tracker) -> new SingletonPalette(
configLoader.loadType(BlockState.class, input, tracker))))
.failThrough(); .failThrough();
} }

View File

@@ -0,0 +1,17 @@
package com.dfsek.terra.api.util.function;
import java.util.function.Consumer;
import java.util.function.Function;
public final class FunctionUtils {
private FunctionUtils() {}
public static <T> Function<T, T> lift(Consumer<T> c) {
return co -> {
c.accept(co);
return co;
};
}
}

View File

@@ -7,81 +7,109 @@
package com.dfsek.terra.api.util.generic.either; package com.dfsek.terra.api.util.generic.either;
import com.dfsek.terra.api.util.function.FunctionUtils;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
public final class Either<L, R> { public interface Either<L, R> {
private final L left; default Either<L, R> ifLeft(Consumer<L> action) {
private final R right; return mapLeft(FunctionUtils.lift(action));
private final boolean leftPresent; }
default Either<L, R> ifRight(Consumer<R> action) {
private Either(L left, R right, boolean leftPresent) { return mapRight(FunctionUtils.lift(action));
this.left = left;
this.right = right;
this.leftPresent = leftPresent;
} }
<L1> Either<L1, R> mapLeft(Function<L, L1> f);
<R1> Either<L, R1> mapRight(Function<R, R1> f);
Optional<L> getLeft();
Optional<R> getRight();
boolean isLeft();
boolean isRight();
@SuppressWarnings({ "rawtypes", "unchecked" })
@NotNull @NotNull
@Contract("_ -> new") @Contract("_ -> new")
public static <L1, R1> Either<L1, R1> left(L1 left) { static <L1, R1> Either<L1, R1> left(L1 left) {
return new Either<>(Objects.requireNonNull(left), null, true); return new Left(Objects.requireNonNull(left));
} }
@SuppressWarnings({ "rawtypes", "unchecked" })
@NotNull @NotNull
@Contract("_ -> new") @Contract("_ -> new")
public static <L1, R1> Either<L1, R1> right(R1 right) { static <L1, R1> Either<L1, R1> right(R1 right) {
return new Either<>(null, Objects.requireNonNull(right), false); return new Right(Objects.requireNonNull(right));
} }
record Left<T>(T value) implements Either<T, Void> {
@NotNull @Override
@Contract("_ -> this") public <L1> Either<L1, Void> mapLeft(Function<T, L1> f) {
public Either<L, R> ifLeft(Consumer<L> action) { return new Left<>(f.apply(value));
if(leftPresent) action.accept(left); }
return this;
@SuppressWarnings({ "unchecked" })
@Override
public <R1> Either<T, R1> mapRight(Function<Void, R1> f) {
return (Either<T, R1>) this;
}
@Override
public Optional<T> getLeft() {
return Optional.of(value);
}
@Override
public Optional<Void> getRight() {
return Optional.empty();
}
@Override
public boolean isLeft() {
return true;
}
@Override
public boolean isRight() {
return false;
}
} }
record Right<T>(T value) implements Either<Void, T> {
@SuppressWarnings({ "unchecked" })
@Override
public <L1> Either<L1, T> mapLeft(Function<Void, L1> f) {
return (Either<L1, T>) this;
}
@NotNull @Override
@Contract("_ -> this") public <R1> Either<Void, R1> mapRight(Function<T, R1> f) {
public Either<L, R> ifRight(Consumer<R> action) { return new Right<>(f.apply(value));
if(!leftPresent) action.accept(right); }
return this;
@Override
public Optional<Void> getLeft() {
return Optional.empty();
}
@Override
public Optional<T> getRight() {
return Optional.of(value);
}
@Override
public boolean isLeft() {
return false;
}
@Override
public boolean isRight() {
return true;
}
} }
}
@NotNull
public Optional<L> getLeft() {
if(leftPresent) return Optional.of(left);
return Optional.empty();
}
@NotNull
public Optional<R> getRight() {
if(!leftPresent) return Optional.of(right);
return Optional.empty();
}
public boolean hasLeft() {
return leftPresent;
}
public boolean hasRight() {
return !leftPresent;
}
@Override
public int hashCode() {
return Objects.hash(left, right);
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Either<?, ?> that)) return false;
return (this.leftPresent && that.leftPresent && Objects.equals(this.left, that.left))
|| (!this.leftPresent && !that.leftPresent && Objects.equals(this.right, that.right));
}
}