Skip to content

Commit

Permalink
Add Option#mapTry() (#2977)
Browse files Browse the repository at this point in the history
Add `mapTry` method to Option, which is a shortcut for
`.toTry().mapTry`:
* when mapping an optional using a checked method, I find it intuitive
that the type changes to a Try, and `mapTry` methods exist on other
types already
* I initially added it onto `Value` but this ran into an issue where a
method with same name but return value already exists on subtype`Future`
  
----

Rebase of #2950
  • Loading branch information
bvkatwijk authored Jan 12, 2025
1 parent 5f6207c commit 3797b05
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
15 changes: 15 additions & 0 deletions vavr/src/main/java/io/vavr/control/Option.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package io.vavr.control;

import io.vavr.CheckedFunction1;
import io.vavr.PartialFunction;
import io.vavr.Tuple;
import io.vavr.Value;
Expand Down Expand Up @@ -391,6 +392,20 @@ default <U> Option<U> map(Function<? super T, ? extends U> mapper) {
return isEmpty() ? none() : some(mapper.apply(get()));
}


/**
* Converts this to a {@link Try}, then runs the given checked function if this is a {@link Try.Success},
* passing the result of the current expression to it.
*
* @param <U> The new component type
* @param mapper A checked function
* @return a {@code Try}
* @throws NullPointerException if {@code mapper} is null
*/
default <U> Try<U> mapTry(CheckedFunction1<? super T, ? extends U> mapper) {
return toTry().mapTry(mapper);
}

/**
* Folds either the {@code None} or the {@code Some} side of the Option value.
*
Expand Down
30 changes: 30 additions & 0 deletions vavr/src/test/java/io/vavr/control/OptionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.vavr.PartialFunction;
import io.vavr.Serializables;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.util.*;
Expand Down Expand Up @@ -361,6 +362,35 @@ public void shouldMapNone() {
assertThat(Option.<Integer> none().map(String::valueOf)).isEqualTo(Option.none());
}

@Nested
class MapTry {
@Test
public void shouldMapTrySome() {
assertThat(Option.of(1).mapTry(String::valueOf)).isEqualTo(Try.success("1"));
}

@Test
public void shouldMapTryNone() {
Try<String> result = Option.none().mapTry(String::valueOf);
assertThat(result.isFailure()).isTrue();
assertThat(result.getCause().getClass()).isEqualTo(NoSuchElementException.class);
assertThat(result.getCause().getMessage()).isEqualTo("No value present");
}

@Test
public void shouldMapTryCheckedException() {
Try<Integer> result = Option.of("a")
.mapTry(this::checkedFunction);
assertThat(result.isFailure()).isTrue();
assertThat(result.getCause().getClass()).isEqualTo(Exception.class);
assertThat(result.getCause().getMessage()).isEqualTo("message");
}

private Integer checkedFunction(String string) throws Exception {
throw new Exception("message");
}
}

// -- flatMap

@Test
Expand Down

0 comments on commit 3797b05

Please sign in to comment.