diff --git a/CHANGELOG b/CHANGELOG index 7851cc2..5db0e0f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,13 @@ CHANGELOG ========= +0.11.0 + +* Rename `Result.maybeThen()` as `Result.flatMapMaybe()` +* Add `Maybe.match(Consumer,Runnable)` +* Add `Maybe.isJust()` +* Add `Maybe.isNothing()` + 0.10.0 ------ diff --git a/src/main/java/net/kemitix/mon/maybe/Just.java b/src/main/java/net/kemitix/mon/maybe/Just.java index 85aea43..9dea530 100644 --- a/src/main/java/net/kemitix/mon/maybe/Just.java +++ b/src/main/java/net/kemitix/mon/maybe/Just.java @@ -44,6 +44,16 @@ final class Just implements Maybe { private final T value; + @Override + public boolean isJust() { + return true; + } + + @Override + public boolean isNothing() { + return false; + } + @Override public Maybe flatMap(final Function> f) { return f.apply(value); @@ -98,6 +108,11 @@ final class Just implements Maybe { // ignore - not nothing } + @Override + public void match(final Consumer justMatcher, final Runnable nothingMatcher) { + justMatcher.accept(value); + } + @Override public void orElseThrow(final Supplier e) { // do not throw diff --git a/src/main/java/net/kemitix/mon/maybe/Maybe.java b/src/main/java/net/kemitix/mon/maybe/Maybe.java index be04b67..0093c53 100644 --- a/src/main/java/net/kemitix/mon/maybe/Maybe.java +++ b/src/main/java/net/kemitix/mon/maybe/Maybe.java @@ -76,6 +76,20 @@ public interface Maybe extends Functor> { 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. * @@ -149,4 +163,12 @@ public interface Maybe extends Functor> { * @param runnable the runnable to call if this is a Nothing */ 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 justMatcher, Runnable nothingMatcher); } diff --git a/src/main/java/net/kemitix/mon/maybe/Nothing.java b/src/main/java/net/kemitix/mon/maybe/Nothing.java index d1c7193..58f169d 100644 --- a/src/main/java/net/kemitix/mon/maybe/Nothing.java +++ b/src/main/java/net/kemitix/mon/maybe/Nothing.java @@ -34,10 +34,21 @@ import java.util.stream.Stream; * @param the type of the missing content * @author Paul Campbell (pcampbell@kemitix.net) */ +@SuppressWarnings("methodcount") final class Nothing implements Maybe { static final Maybe INSTANCE = new Nothing<>(); + @Override + public boolean isJust() { + return false; + } + + @Override + public boolean isNothing() { + return true; + } + @Override public Maybe flatMap(final Function> f) { return Maybe.nothing(); @@ -79,6 +90,11 @@ final class Nothing implements Maybe { runnable.run(); } + @Override + public void match(final Consumer justMatcher, final Runnable nothingMatcher) { + nothingMatcher.run(); + } + @Override public void orElseThrow(final Supplier e) throws Exception { throw e.get(); diff --git a/src/main/java/net/kemitix/mon/result/Result.java b/src/main/java/net/kemitix/mon/result/Result.java index 9b82836..72cafdb 100644 --- a/src/main/java/net/kemitix/mon/result/Result.java +++ b/src/main/java/net/kemitix/mon/result/Result.java @@ -129,19 +129,19 @@ public interface Result extends Functor> { * @param the type of the updated Result * @return a new Maybe within a Result */ - static Result> maybeThen(Result> maybeResult, Function, Result>> f) { + static Result> flatMapMaybe(Result> maybeResult, Function, Result>> 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. */ boolean isError(); /** - * Checks of the Result is a success. + * Checks if the Result is a success. * * @return true if the Result is a success. */ diff --git a/src/test/java/net/kemitix/mon/MaybeTest.java b/src/test/java/net/kemitix/mon/MaybeTest.java index 2b82337..74c6efe 100644 --- a/src/test/java/net/kemitix/mon/MaybeTest.java +++ b/src/test/java/net/kemitix/mon/MaybeTest.java @@ -22,7 +22,7 @@ public class MaybeTest implements WithAssertions { @Test public void justMustBeNonNull() { assertThatNullPointerException().isThrownBy(() -> just(null)) - .withMessageContaining("value"); + .withMessageContaining("value"); } @Test @@ -84,7 +84,7 @@ public class MaybeTest implements WithAssertions { public void toOptional() { assertThat(just(1).toOptional()).isEqualTo(Optional.of(1)); assertThat(nothing() - .toOptional()).isEqualTo(Optional.empty()); + .toOptional()).isEqualTo(Optional.empty()); } @Test @@ -194,4 +194,69 @@ public class MaybeTest implements WithAssertions { assertThat(capture).isTrue(); } + @Test + public void just_whenMatch_thenJustTriggers() { + //given + final Maybe maybe = Maybe.just(1); + //then + maybe.match( + just -> assertThat(just).isEqualTo(1), + () -> fail("Not nothing") + ); + } + + @Test + public void nothing_whenMatch_thenNothingTriggers() { + //given + final Maybe 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 maybe = just(1); + //when + final boolean isJust = maybe.isJust(); + //then + assertThat(isJust).isTrue(); + } + + @Test + public void just_isNothing_isFalse() { + //given + final Maybe maybe = just(1); + //when + final boolean isNothing = maybe.isNothing(); + //then + assertThat(isNothing).isFalse(); + } + + @Test + public void nothing_isJust_isFalse() { + //given + final Maybe maybe = nothing(); + //when + final boolean isJust = maybe.isJust(); + //then + assertThat(isJust).isFalse(); + } + + @Test + public void nothing_isNothing_isTrue() { + //given + final Maybe maybe = nothing(); + //when + final boolean isNothing = maybe.isNothing(); + //then + assertThat(isNothing).isTrue(); + } + } diff --git a/src/test/java/net/kemitix/mon/ResultTest.java b/src/test/java/net/kemitix/mon/ResultTest.java index 8956906..edda0e3 100644 --- a/src/test/java/net/kemitix/mon/ResultTest.java +++ b/src/test/java/net/kemitix/mon/ResultTest.java @@ -605,24 +605,24 @@ public class ResultTest implements WithAssertions { } @Test - public void okayJust_whenMaybeThen_whereOkayJust_thenIsOkayJust() { + public void okayJust_whenFlatMapMaybe_whereOkayJust_thenIsOkayJust() { //given final Result> okJust = Result.ok(Maybe.just(1)); //when - final Result> result = Result.maybeThen(okJust, mv -> Result.ok(Maybe.just(2))); + final Result> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2")))); //then result.match( - success -> assertThat(success.toOptional()).contains(2), + success -> assertThat(success.toOptional()).contains("2"), error -> fail("Not an error") ); } @Test - public void okayJust_whenMaybeThen_whereOkayNothing_thenIsOkayNothing() { + public void okayJust_whenFlatMapMaybe_whereOkayNothing_thenIsOkayNothing() { //given final Result> okJust = Result.ok(Maybe.just(1)); //when - final Result> result = Result.maybeThen(okJust, v -> Result.ok(Maybe.nothing())); + final Result> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.nothing()))); //then result.match( success -> assertThat(success.toOptional()).isEmpty(), @@ -631,12 +631,12 @@ public class ResultTest implements WithAssertions { } @Test - public void okayJust_whenMaybeThen_whereError_thenIsError() { + public void okayJust_whenFlatMapMaybe_whereError_thenIsError() { //given final Result> okJust = Result.ok(Maybe.just(1)); final RuntimeException exception = new RuntimeException(); //when - final Result> result = Result.maybeThen(okJust, v -> Result.error(exception)); + final Result> result = Result.flatMapMaybe(okJust, v -> Result.error(exception)); //then result.match( success -> fail("Not a success"), @@ -645,27 +645,27 @@ public class ResultTest implements WithAssertions { } @Test - public void okayNothing_whenMaybeThen_thenDoNotApply() { + public void okayNothing_whenFlatMapMaybe_thenDoNotApply() { //given final Result> okNothing = Result.ok(Maybe.nothing()); //when - final Result> result = Result.maybeThen(okNothing, v -> Result.ok(Maybe.just(2))); + final Result> result = Result.flatMapMaybe(okNothing, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2")))); //then - okNothing.match( + result.match( success -> assertThat(success.toOptional()).isEmpty(), error -> fail("Not an error") ); } @Test - public void error_whenMaybeThen_thenDoNotApply() { + public void error_whenFlatMapMaybe_thenDoNotApply() { //given final RuntimeException exception = new RuntimeException(); final Result> maybeResult = Result.error(exception); //when - final Result> result = Result.maybeThen(maybeResult, v -> Result.ok(Maybe.just(2))); + final Result> result = Result.flatMapMaybe(maybeResult, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2")))); //then - maybeResult.match( + result.match( success -> fail("Not a success"), error -> assertThat(error).isSameAs(exception) );