139 lines
3.8 KiB
Java
139 lines
3.8 KiB
Java
package io.gitlab.jfronny.commons.switchsupport;
|
|
|
|
import java.util.Optional;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import java.util.function.Predicate;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Stream;
|
|
|
|
public sealed interface Opt<T> {
|
|
record Some<T>(T value) implements Opt<T> {
|
|
public static <T> Some<T> of(T value) {
|
|
return new Some<>(value);
|
|
}
|
|
}
|
|
|
|
record None<T>() implements Opt<T> {
|
|
public static <T> None<T> of() {
|
|
return new None<>();
|
|
}
|
|
}
|
|
|
|
static <T> Opt<T> empty() {
|
|
return None.of();
|
|
}
|
|
|
|
static <T> Opt<T> of(T value) {
|
|
return value == null ? None.of() : Some.of(value);
|
|
}
|
|
|
|
/**
|
|
* Converts an Optional to an Opt.
|
|
* Useful as a static import for switching over Optionals.
|
|
*
|
|
* @param optional Optional to convert to Opt
|
|
* @param <T> Type of the Optional
|
|
* @return Opt of the Optional
|
|
*/
|
|
static <T> Opt<T> over(Optional<T> optional) {
|
|
return optional.map(Opt::of).orElseGet(Opt::empty);
|
|
}
|
|
|
|
default T get() {
|
|
return switch (this) {
|
|
case Some(var value) -> value;
|
|
case None none -> throw new IllegalStateException("Opt is None");
|
|
};
|
|
}
|
|
|
|
default T getOrElse(T defaultValue) {
|
|
return switch (this) {
|
|
case Some(var value) -> value;
|
|
case None none -> defaultValue;
|
|
};
|
|
}
|
|
|
|
default T getOrElseGet(Supplier<T> supplier) {
|
|
return switch (this) {
|
|
case Some(var value) -> value;
|
|
case None none -> supplier.get();
|
|
};
|
|
}
|
|
|
|
default <X extends Throwable> T getOrElseThrow(Supplier<X> exceptionSupplier) throws X {
|
|
return switch (this) {
|
|
case Some(var value) -> value;
|
|
case None none -> throw exceptionSupplier.get();
|
|
};
|
|
}
|
|
|
|
default <R> Opt<R> map(Function<T, R> mapper) {
|
|
return switch (this) {
|
|
case Some(var value) -> Some.of(mapper.apply(value));
|
|
case None none -> None.of();
|
|
};
|
|
}
|
|
|
|
default <R> Opt<R> flatMap(Function<T, Opt<R>> mapper) {
|
|
return switch (this) {
|
|
case Some(var value) -> mapper.apply(value);
|
|
case None none -> None.of();
|
|
};
|
|
}
|
|
|
|
default void ifPresent(Consumer<T> consumer) {
|
|
if (this instanceof Some(var value)) consumer.accept(value);
|
|
}
|
|
|
|
default void ifPresentOrElse(Consumer<T> consumer, Runnable runnable) {
|
|
switch (this) {
|
|
case Some(var value) -> consumer.accept(value);
|
|
case None none -> runnable.run();
|
|
}
|
|
}
|
|
|
|
default Opt<T> filter(Predicate<T> predicate) {
|
|
return switch (this) {
|
|
case Some(var value) when predicate.test(value) -> this;
|
|
case Some some -> None.of();
|
|
case None none -> this;
|
|
};
|
|
}
|
|
|
|
default Opt<T> or(Supplier<Opt<T>> supplier) {
|
|
return switch (this) {
|
|
case Some some -> this;
|
|
case None none -> supplier.get();
|
|
};
|
|
}
|
|
|
|
default Opt<T> orElse(Opt<T> other) {
|
|
return switch (this) {
|
|
case Some some -> this;
|
|
case None none -> other;
|
|
};
|
|
}
|
|
|
|
default T orElseGet(Supplier<T> supplier) {
|
|
return switch (this) {
|
|
case Some(var value) -> value;
|
|
case None none -> supplier.get();
|
|
};
|
|
}
|
|
|
|
default <X> Result<T, X> toResult(Supplier<X> errorSupplier) {
|
|
return switch (this) {
|
|
case Some(var value) -> Result.success(value);
|
|
case None none -> Result.failure(errorSupplier.get());
|
|
};
|
|
}
|
|
|
|
default Stream<T> stream() {
|
|
return switch (this) {
|
|
case Some(var value) -> Stream.of(value);
|
|
case None none -> Stream.empty();
|
|
};
|
|
}
|
|
}
|