Add andThen(Function)
This commit is contained in:
parent
c8bdd77ac9
commit
fb6b65e6de
5 changed files with 93 additions and 2 deletions
|
@ -1,6 +1,11 @@
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.10.0
|
||||||
|
------
|
||||||
|
|
||||||
|
* Add `andThen(Function)`
|
||||||
|
|
||||||
0.9.0
|
0.9.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import lombok.RequiredArgsConstructor;
|
||||||
import net.kemitix.mon.maybe.Maybe;
|
import net.kemitix.mon.maybe.Maybe;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -90,6 +91,11 @@ class Err<T> implements Result<T> {
|
||||||
errorConsumer.accept(error);
|
errorConsumer.accept(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> Result<R> andThen(final Function<T, Callable<R>> f) {
|
||||||
|
return Result.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object other) {
|
public boolean equals(final Object other) {
|
||||||
return other instanceof Err && Objects.equals(error, ((Err) other).error);
|
return other instanceof Err && Objects.equals(error, ((Err) other).error);
|
||||||
|
|
|
@ -196,4 +196,25 @@ public interface Result<T> extends Functor<T, Result<?>> {
|
||||||
* @param errorConsumer the consumer to handle the error
|
* @param errorConsumer the consumer to handle the error
|
||||||
*/
|
*/
|
||||||
void onError(Consumer<Throwable> errorConsumer);
|
void onError(Consumer<Throwable> errorConsumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps a Success Result to another Result using a Callable that is able to throw a checked exception.
|
||||||
|
*
|
||||||
|
* <p>Combination of {@link #flatMap(Function)} and {@link #of(Callable)}.</p>
|
||||||
|
*
|
||||||
|
* <p>Syntax is:</p>
|
||||||
|
* <pre><code>
|
||||||
|
* Integer doSomething() {...}
|
||||||
|
* String doSomethingElse(final Integer value) {...}
|
||||||
|
* Result<String> r = Result.of(() -> doSomething())
|
||||||
|
* .andThen(value -> () -> doSomethingElse(value));
|
||||||
|
* </code></pre>
|
||||||
|
*
|
||||||
|
* <p>When the Result is an Err, then the original error is carried over and the Callable is never called.</p>
|
||||||
|
*
|
||||||
|
* @param f the function to map the Success value to the Callable
|
||||||
|
* @param <R> the type of the final Result
|
||||||
|
* @return a new Result
|
||||||
|
*/
|
||||||
|
<R> Result<R> andThen(Function<T, Callable<R>> f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import lombok.RequiredArgsConstructor;
|
||||||
import net.kemitix.mon.maybe.Maybe;
|
import net.kemitix.mon.maybe.Maybe;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -94,6 +95,11 @@ class Success<T> implements Result<T> {
|
||||||
// do nothing - this is not an error
|
// do nothing - this is not an error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> Result<R> andThen(final Function<T, Callable<R>> f) {
|
||||||
|
return Result.of(f.apply(value));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object other) {
|
public boolean equals(final Object other) {
|
||||||
return other instanceof Success && Objects.equals(value, ((Success) other).value);
|
return other instanceof Success && Objects.equals(value, ((Success) other).value);
|
||||||
|
|
|
@ -452,14 +452,16 @@ public class ResultTest implements WithAssertions {
|
||||||
assertThat(peeked).isSameAs(result);
|
assertThat(peeked).isSameAs(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void success_whenOnError_thenIgnore() {
|
@Test
|
||||||
|
public void success_whenOnError_thenIgnore() {
|
||||||
//given
|
//given
|
||||||
final Result<Integer> ok = Result.ok(1);
|
final Result<Integer> ok = Result.ok(1);
|
||||||
//when
|
//when
|
||||||
ok.onError(e -> fail("not an error"));
|
ok.onError(e -> fail("not an error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void error_whenOnError_thenConsume() {
|
@Test
|
||||||
|
public void error_whenOnError_thenConsume() {
|
||||||
//given
|
//given
|
||||||
final RuntimeException exception = new RuntimeException();
|
final RuntimeException exception = new RuntimeException();
|
||||||
final Result<Integer> error = Result.error(exception);
|
final Result<Integer> error = Result.error(exception);
|
||||||
|
@ -500,6 +502,57 @@ public class ResultTest implements WithAssertions {
|
||||||
recovered.onError(e -> assertThat(e).hasMessage("updated"));
|
recovered.onError(e -> assertThat(e).hasMessage("updated"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void success_andThenSuccess_thenSuccess() {
|
||||||
|
//given
|
||||||
|
final Result<Integer> ok = Result.ok(1);
|
||||||
|
//when
|
||||||
|
final Result<String> result = ok.andThen(v -> () -> "success");
|
||||||
|
//then
|
||||||
|
assertThat(result.isOkay()).isTrue();
|
||||||
|
result.peek(v -> assertThat(v).isEqualTo("success"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void success_andThenError_thenError() {
|
||||||
|
//given
|
||||||
|
final Result<Integer> ok = Result.ok(1);
|
||||||
|
final RuntimeException exception = new RuntimeException();
|
||||||
|
//when
|
||||||
|
final Result<Object> result = ok.andThen(v -> () -> {
|
||||||
|
throw exception;
|
||||||
|
});
|
||||||
|
//then
|
||||||
|
assertThat(result.isError()).isTrue();
|
||||||
|
result.onError(e -> assertThat(e).isSameAs(exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void error_andThenSuccess_thenError() {
|
||||||
|
//given
|
||||||
|
final RuntimeException exception = new RuntimeException();
|
||||||
|
final Result<Object> error = Result.error(exception);
|
||||||
|
//when
|
||||||
|
final Result<Object> result = error.andThen(v -> () -> "success");
|
||||||
|
//then
|
||||||
|
assertThat(result.isError()).isTrue();
|
||||||
|
result.onError(e -> assertThat(e).isSameAs(exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void error_andThenError_thenError() {
|
||||||
|
//given
|
||||||
|
final RuntimeException exception1 = new RuntimeException();
|
||||||
|
final Result<Object> error = Result.error(exception1);
|
||||||
|
//when
|
||||||
|
final Result<Object> result = error.andThen(v -> () -> {
|
||||||
|
throw new RuntimeException();
|
||||||
|
});
|
||||||
|
//then
|
||||||
|
assertThat(result.isError()).isTrue();
|
||||||
|
result.onError(e -> assertThat(e).isSameAs(exception1));
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
private static class UseCase {
|
private static class UseCase {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue