Skip to content

Commit

Permalink
Add Result.unsafeFlatten (#11)
Browse files Browse the repository at this point in the history
Signed-off-by: David Greven <[email protected]>
Signed-off-by: Sebastian Becker <[email protected]>
  • Loading branch information
grevend-bosch committed Nov 15, 2021
1 parent c8f9fde commit dd26177
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,27 @@ void flatMapNullPointerException() {
.isExactlyInstanceOf(NullPointerException.class);
}

@Test
void unsafeFlattenNestedFailure() {
int reason = 21;
Result<Integer, Result<Integer, Integer>> res = new Failure<>(new Failure<>(reason));
assertThat(res.unsafeFlatten()).hasReason(reason);
}

@Test
void unsafeFlattenSuccessNestedInFailure() {
int value = 12;
Result<Integer, Result<Integer, Integer>> res = new Failure<>(new Success<>(value));
assertThat(res.unsafeFlatten()).hasValue(value);
}

@Test
void unsafeFlattenNonNestedFailure() {
int reason = 21;
Result<Integer, Integer> res = new Failure<>(reason);
assertThat(res.unsafeFlatten()).hasReason(reason);
}

@Test
void fold() {
assertThat(result.<Integer>fold(v -> v * 2, r -> r + 9)).isEqualTo(30);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ void flatMapNullPointerException() {
.isExactlyInstanceOf(NullPointerException.class);
}

@Test
void unsafeFlattenNestedSuccess() {
int value = 12;
Result<Result<Integer, Integer>, Integer> res = new Success<>(new Success<>(value));
assertThat(res.unsafeFlatten()).hasValue(value);
}

@Test
void unsafeFlattenFailureNestedInSuccess() {
int reason = 21;
Result<Result<Integer, Integer>, Integer> res = new Success<>(new Failure<>(reason));
assertThat(res.unsafeFlatten()).hasReason(reason);
}

@Test
void unsafeFlattenNonNestedSuccess() {
int value = 12;
Result<Integer, Integer> res = new Success<>(value);
assertThat(res.unsafeFlatten()).hasValue(value);
}

@Test
void fold() {
assertThat(result.<Integer>fold(v -> v * 2, r -> r + 9)).isEqualTo(24);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,23 @@ public <N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N
return new Failure<>(this.reason());
}

/**
* {@inheritDoc}
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @version JDK 8
* @since 0.1.0
*/
@Override
@SuppressWarnings("unchecked")
public <V, R> Result<V, R> unsafeFlatten() {
return (Result<V, R>) (reason() instanceof Result ? ((Result) reason()) : this);
}

/**
* {@inheritDoc}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ default boolean isFailure() {
*/
<N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N, F>> function);

/**
* Flattens the directly nested {@code Result} if available.
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @since 0.1.0
*/
<V, R> Result<V, R> unsafeFlatten();

/**
* If the {@code Result} is a {@link Failure}, the failure function is
* applied to the {@link Failure#reason()}. Otherwise, the success
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,23 @@ public <N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N
return requireNonNull((Result<N, F>) function.apply(this.value()));
}

/**
* {@inheritDoc}
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @version JDK 8
* @since 0.1.0
*/
@Override
@SuppressWarnings("unchecked")
public <V, R> Result<V, R> unsafeFlatten() {
return (Result<V, R>) (value() instanceof Result ? ((Result) value()) : this);
}

/**
* {@inheritDoc}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,23 @@ public <N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N
return new Failure<>(this.reason());
}

/**
* {@inheritDoc}
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @version JDK 17
* @since 0.1.0
*/
@Override
@SuppressWarnings("unchecked")
public <V, R> Result<V, R> unsafeFlatten() {
return (Result<V, R>) (reason() instanceof Result nested ? nested : this);
}

/**
* {@inheritDoc}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ default boolean isFailure() {
*/
<N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N, F>> function);

/**
* Flattens the directly nested {@code Result} if available.
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @since 0.1.0
*/
<V, R> Result<V, R> unsafeFlatten();

/**
* If the {@code Result} is a {@link Failure}, the failure function is
* applied to the {@link Failure#reason()}. Otherwise, the success
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,23 @@ public <N> Result<N, F> flatMap(Function<? super S, ? extends Result<? extends N
return requireNonNull((Result<N, F>) function.apply(this.value()));
}

/**
* {@inheritDoc}
*
* @param <V> the new success value type
* @param <R> the new failure reason type
* @return a one level flattened {@code Result}
* @throws ClassCastException if the nested {@code Result} type parameters
* do not align with {@code V} and {@code R}
* @version JDK 17
* @since 0.1.0
*/
@Override
@SuppressWarnings("unchecked")
public <V, R> Result<V, R> unsafeFlatten() {
return (Result<V, R>) (value() instanceof Result nested ? nested : this);
}

/**
* {@inheritDoc}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,31 @@ void result() {
assertThat(res.stream().toList()).isEmpty();
}

@Test
void unsafeFlatten() {
var value = 12;
var reason = 21;

assertThat(new Success<>(new Success<>(value)).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(value);
assertThat(new Success<>(new Failure<>(reason)).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(reason);
assertThat(new Success<>(value).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(value);

assertThat(new Failure<>(new Failure<>(reason)).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(reason);
assertThat(new Failure<>(new Success<>(value)).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(value);
assertThat(new Failure<>(reason).unsafeFlatten()
.<Integer>fold(identity(), identity())).isEqualTo(reason);
}

@Test
void swap() {
var value = 12;
var res = new Success<Integer, Integer>(value);

assertThat(res.<Integer>fold(identity(), r -> -1)).isEqualTo(value);
assertThat(res.swap().<Integer>fold(identity(), r -> -1)).isEqualTo(-1);
assertThat(res.swap().swap().<Integer>fold(identity(), r -> -1)).isEqualTo(value);
Expand Down

0 comments on commit dd26177

Please sign in to comment.