commit
a9d28c9950
7 changed files with 143 additions and 18 deletions
|
@ -1,6 +1,13 @@
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.11.0
|
||||||
|
|
||||||
|
* Rename `Result.maybeThen()` as `Result.flatMapMaybe()`
|
||||||
|
* Add `Maybe.match(Consumer,Runnable)`
|
||||||
|
* Add `Maybe.isJust()`
|
||||||
|
* Add `Maybe.isNothing()`
|
||||||
|
|
||||||
0.10.0
|
0.10.0
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,16 @@ final class Just<T> implements Maybe<T> {
|
||||||
|
|
||||||
private final T value;
|
private final T value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJust() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNothing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
|
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
|
||||||
return f.apply(value);
|
return f.apply(value);
|
||||||
|
@ -98,6 +108,11 @@ final class Just<T> implements Maybe<T> {
|
||||||
// ignore - not nothing
|
// ignore - not nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void match(final Consumer<T> justMatcher, final Runnable nothingMatcher) {
|
||||||
|
justMatcher.accept(value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void orElseThrow(final Supplier<Exception> e) {
|
public void orElseThrow(final Supplier<Exception> e) {
|
||||||
// do not throw
|
// do not throw
|
||||||
|
|
|
@ -76,6 +76,20 @@ public interface Maybe<T> extends Functor<T, Maybe<?>> {
|
||||||
return just(value);
|
return just(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the Maybe is a Just.
|
||||||
|
*
|
||||||
|
* @return true if the Maybe is a Just
|
||||||
|
*/
|
||||||
|
boolean isJust();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the Maybe is Nothing.
|
||||||
|
*
|
||||||
|
* @return true if the Maybe is Nothing
|
||||||
|
*/
|
||||||
|
boolean isNothing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monad binder maps the Maybe into another Maybe using the binder method f.
|
* Monad binder maps the Maybe into another Maybe using the binder method f.
|
||||||
*
|
*
|
||||||
|
@ -149,4 +163,12 @@ public interface Maybe<T> extends Functor<T, Maybe<?>> {
|
||||||
* @param runnable the runnable to call if this is a Nothing
|
* @param runnable the runnable to call if this is a Nothing
|
||||||
*/
|
*/
|
||||||
void ifNothing(Runnable runnable);
|
void ifNothing(Runnable runnable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the Maybe, either just or nothing, and performs either the Consumer, for Just, or Runnable for nothing.
|
||||||
|
*
|
||||||
|
* @param justMatcher the Consumer to pass the value of a Just to
|
||||||
|
* @param nothingMatcher the Runnable to call if the Maybe is a Nothing
|
||||||
|
*/
|
||||||
|
void match(Consumer<T> justMatcher, Runnable nothingMatcher);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,21 @@ import java.util.stream.Stream;
|
||||||
* @param <T> the type of the missing content
|
* @param <T> the type of the missing content
|
||||||
* @author Paul Campbell (pcampbell@kemitix.net)
|
* @author Paul Campbell (pcampbell@kemitix.net)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("methodcount")
|
||||||
final class Nothing<T> implements Maybe<T> {
|
final class Nothing<T> implements Maybe<T> {
|
||||||
|
|
||||||
static final Maybe<?> INSTANCE = new Nothing<>();
|
static final Maybe<?> INSTANCE = new Nothing<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isJust() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNothing() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
|
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
|
||||||
return Maybe.nothing();
|
return Maybe.nothing();
|
||||||
|
@ -79,6 +90,11 @@ final class Nothing<T> implements Maybe<T> {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void match(final Consumer<T> justMatcher, final Runnable nothingMatcher) {
|
||||||
|
nothingMatcher.run();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void orElseThrow(final Supplier<Exception> e) throws Exception {
|
public void orElseThrow(final Supplier<Exception> e) throws Exception {
|
||||||
throw e.get();
|
throw e.get();
|
||||||
|
|
|
@ -129,19 +129,19 @@ public interface Result<T> extends Functor<T, Result<?>> {
|
||||||
* @param <R> the type of the updated Result
|
* @param <R> the type of the updated Result
|
||||||
* @return a new Maybe within a Result
|
* @return a new Maybe within a Result
|
||||||
*/
|
*/
|
||||||
static <T, R> Result<Maybe<R>> maybeThen(Result<Maybe<T>> maybeResult, Function<Maybe<T>, Result<Maybe<R>>> f) {
|
static <T, R> Result<Maybe<R>> flatMapMaybe(Result<Maybe<T>> maybeResult, Function<Maybe<T>, Result<Maybe<R>>> f) {
|
||||||
return maybeResult.flatMap(f);
|
return maybeResult.flatMap(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks of the Result is an error.
|
* Checks if the Result is an error.
|
||||||
*
|
*
|
||||||
* @return true if the Result is an error.
|
* @return true if the Result is an error.
|
||||||
*/
|
*/
|
||||||
boolean isError();
|
boolean isError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks of the Result is a success.
|
* Checks if the Result is a success.
|
||||||
*
|
*
|
||||||
* @return true if the Result is a success.
|
* @return true if the Result is a success.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class MaybeTest implements WithAssertions {
|
||||||
@Test
|
@Test
|
||||||
public void justMustBeNonNull() {
|
public void justMustBeNonNull() {
|
||||||
assertThatNullPointerException().isThrownBy(() -> just(null))
|
assertThatNullPointerException().isThrownBy(() -> just(null))
|
||||||
.withMessageContaining("value");
|
.withMessageContaining("value");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -84,7 +84,7 @@ public class MaybeTest implements WithAssertions {
|
||||||
public void toOptional() {
|
public void toOptional() {
|
||||||
assertThat(just(1).toOptional()).isEqualTo(Optional.of(1));
|
assertThat(just(1).toOptional()).isEqualTo(Optional.of(1));
|
||||||
assertThat(nothing()
|
assertThat(nothing()
|
||||||
.toOptional()).isEqualTo(Optional.empty());
|
.toOptional()).isEqualTo(Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -194,4 +194,69 @@ public class MaybeTest implements WithAssertions {
|
||||||
assertThat(capture).isTrue();
|
assertThat(capture).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void just_whenMatch_thenJustTriggers() {
|
||||||
|
//given
|
||||||
|
final Maybe<Integer> maybe = Maybe.just(1);
|
||||||
|
//then
|
||||||
|
maybe.match(
|
||||||
|
just -> assertThat(just).isEqualTo(1),
|
||||||
|
() -> fail("Not nothing")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nothing_whenMatch_thenNothingTriggers() {
|
||||||
|
//given
|
||||||
|
final Maybe<Integer> maybe = Maybe.nothing();
|
||||||
|
final AtomicBoolean flag = new AtomicBoolean(false);
|
||||||
|
//when
|
||||||
|
maybe.match(
|
||||||
|
just -> fail("Not a just"),
|
||||||
|
() -> flag.set(true)
|
||||||
|
);
|
||||||
|
//then
|
||||||
|
assertThat(flag).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void just_isJust_isTrue() {
|
||||||
|
//given
|
||||||
|
final Maybe<Integer> maybe = just(1);
|
||||||
|
//when
|
||||||
|
final boolean isJust = maybe.isJust();
|
||||||
|
//then
|
||||||
|
assertThat(isJust).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void just_isNothing_isFalse() {
|
||||||
|
//given
|
||||||
|
final Maybe<Integer> maybe = just(1);
|
||||||
|
//when
|
||||||
|
final boolean isNothing = maybe.isNothing();
|
||||||
|
//then
|
||||||
|
assertThat(isNothing).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nothing_isJust_isFalse() {
|
||||||
|
//given
|
||||||
|
final Maybe<Object> maybe = nothing();
|
||||||
|
//when
|
||||||
|
final boolean isJust = maybe.isJust();
|
||||||
|
//then
|
||||||
|
assertThat(isJust).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nothing_isNothing_isTrue() {
|
||||||
|
//given
|
||||||
|
final Maybe<Object> maybe = nothing();
|
||||||
|
//when
|
||||||
|
final boolean isNothing = maybe.isNothing();
|
||||||
|
//then
|
||||||
|
assertThat(isNothing).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -605,24 +605,24 @@ public class ResultTest implements WithAssertions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void okayJust_whenMaybeThen_whereOkayJust_thenIsOkayJust() {
|
public void okayJust_whenFlatMapMaybe_whereOkayJust_thenIsOkayJust() {
|
||||||
//given
|
//given
|
||||||
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
||||||
//when
|
//when
|
||||||
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, mv -> Result.ok(Maybe.just(2)));
|
final Result<Maybe<String>> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
|
||||||
//then
|
//then
|
||||||
result.match(
|
result.match(
|
||||||
success -> assertThat(success.toOptional()).contains(2),
|
success -> assertThat(success.toOptional()).contains("2"),
|
||||||
error -> fail("Not an error")
|
error -> fail("Not an error")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void okayJust_whenMaybeThen_whereOkayNothing_thenIsOkayNothing() {
|
public void okayJust_whenFlatMapMaybe_whereOkayNothing_thenIsOkayNothing() {
|
||||||
//given
|
//given
|
||||||
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
||||||
//when
|
//when
|
||||||
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, v -> Result.ok(Maybe.nothing()));
|
final Result<Maybe<String>> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.nothing())));
|
||||||
//then
|
//then
|
||||||
result.match(
|
result.match(
|
||||||
success -> assertThat(success.toOptional()).isEmpty(),
|
success -> assertThat(success.toOptional()).isEmpty(),
|
||||||
|
@ -631,12 +631,12 @@ public class ResultTest implements WithAssertions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void okayJust_whenMaybeThen_whereError_thenIsError() {
|
public void okayJust_whenFlatMapMaybe_whereError_thenIsError() {
|
||||||
//given
|
//given
|
||||||
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
|
||||||
final RuntimeException exception = new RuntimeException();
|
final RuntimeException exception = new RuntimeException();
|
||||||
//when
|
//when
|
||||||
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, v -> Result.error(exception));
|
final Result<Maybe<Integer>> result = Result.flatMapMaybe(okJust, v -> Result.error(exception));
|
||||||
//then
|
//then
|
||||||
result.match(
|
result.match(
|
||||||
success -> fail("Not a success"),
|
success -> fail("Not a success"),
|
||||||
|
@ -645,27 +645,27 @@ public class ResultTest implements WithAssertions {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void okayNothing_whenMaybeThen_thenDoNotApply() {
|
public void okayNothing_whenFlatMapMaybe_thenDoNotApply() {
|
||||||
//given
|
//given
|
||||||
final Result<Maybe<Integer>> okNothing = Result.ok(Maybe.nothing());
|
final Result<Maybe<Integer>> okNothing = Result.ok(Maybe.nothing());
|
||||||
//when
|
//when
|
||||||
final Result<Maybe<Integer>> result = Result.maybeThen(okNothing, v -> Result.ok(Maybe.just(2)));
|
final Result<Maybe<String>> result = Result.flatMapMaybe(okNothing, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
|
||||||
//then
|
//then
|
||||||
okNothing.match(
|
result.match(
|
||||||
success -> assertThat(success.toOptional()).isEmpty(),
|
success -> assertThat(success.toOptional()).isEmpty(),
|
||||||
error -> fail("Not an error")
|
error -> fail("Not an error")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void error_whenMaybeThen_thenDoNotApply() {
|
public void error_whenFlatMapMaybe_thenDoNotApply() {
|
||||||
//given
|
//given
|
||||||
final RuntimeException exception = new RuntimeException();
|
final RuntimeException exception = new RuntimeException();
|
||||||
final Result<Maybe<Integer>> maybeResult = Result.error(exception);
|
final Result<Maybe<Integer>> maybeResult = Result.error(exception);
|
||||||
//when
|
//when
|
||||||
final Result<Maybe<Integer>> result = Result.maybeThen(maybeResult, v -> Result.ok(Maybe.just(2)));
|
final Result<Maybe<String>> result = Result.flatMapMaybe(maybeResult, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
|
||||||
//then
|
//then
|
||||||
maybeResult.match(
|
result.match(
|
||||||
success -> fail("Not a success"),
|
success -> fail("Not a success"),
|
||||||
error -> assertThat(error).isSameAs(exception)
|
error -> assertThat(error).isSameAs(exception)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue