Result micro-library. Emoji powered.
final class Aborted extends Failure { | |
public Result<T> ✅(Consumer<T> f) { | |
return this; | |
} | |
public Result<T> ❌(Consumer<ExceptionStack> f) { | |
return this; | |
} | |
} |
final class ExceptionStack { | |
private Exception[] exceptions; | |
public ExceptionStack(Exception... exceptions) { | |
this.exceptions = exceptions; | |
} | |
public merge(ExceptionStack exceptionStack) { | |
return Stream.of(this.exceptionStack, exceptionStack).flatMap(Stream::of).toArray(ExceptionStack[]::new); | |
} | |
} |
class Failure<T> implements Result<T> { | |
private ExceptionStack exceptionStack; | |
public Failure(ExceptionStack exceptionStack) { | |
this.exceptionStack = exceptionStack; | |
} | |
public Result<T> ✅(Consumer<T> f) { | |
return this; | |
} | |
public Result<T> ❌(Consumer<ExceptionStack> f) { | |
op = Result<ExceptionStack>::result(() -> { | |
f.accept(exceptionStack); | |
return exceptionStack; | |
}); | |
switch (true) { | |
case op instanceof Success<ExceptionStack>: | |
return new Aborted<T>(exStack); | |
case op instanceof Failure<ExceptionStack>: | |
return new Aborted<T>(exceptionStack.merge(deeperExStack)); | |
} | |
} | |
} |
interface Result<T> { | |
default Result<T> get(Supplier<T> f) { | |
try { | |
value = f.get(); | |
return new Success(value); | |
} catch(Exception e) { | |
return new Failure(new ExceptionStack(e)); | |
} | |
} | |
Result<T> ✅(Consumer<T> consumer); | |
Result<T> ❌(Consumer<ExceptionStack> consumer); | |
} |
final class Success<T> implements Result<T> { | |
private T value; | |
public Success(T value) { | |
this.value = value; | |
} | |
public Result<T> ✅(Consumer<T> f) { | |
return Result<T>::execute(() -> { | |
f.accept(value); | |
return value; | |
); | |
} | |
public Result<T> ❌(Consumer<ExceptionStack> f) { | |
return this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment