Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for threaded use of Try.withResources() for up to 3 arguments #2752

Open
wants to merge 1 commit into
base: version/1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions src/main/java/io/vavr/control/Try.java
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,19 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithResources
return new WithResources2<>(t1Supplier, t2Supplier);
}

/**
* Creates a {@code Try}-with-resources builder that operates on two {@link AutoCloseable} chained (dependent) resources.
*
* @param t1Supplier The supplier of the 1st resource.
* @param t2Function A function which takes the supply of t1 and supplies the 2nd resource.
* @param <T1> Type of the 1st resource.
* @param <T2> Type of the 2nd resource.
* @return a new {@link WithThreadedResources2} instance.
*/
public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithThreadedResources2<T1, T2> withResources(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
return new WithThreadedResources2<>(t1Supplier, t2Function);
}

/**
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
*
Expand All @@ -1397,6 +1410,21 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends Au
return new WithResources3<>(t1Supplier, t2Supplier, t3Supplier);
}

/**
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} chained (dependent) resources.
*
* @param t1Supplier The supplier of the 1st resource.
* @param t2Function A function which takes a supply of the 1st resource and supplies the 2nd resource.
* @param t3Function A function which takes a supply of the 2nd resource and supplies the 3rd resource.
* @param <T1> Type of the 1st resource.
* @param <T2> Type of the 2nd resource.
* @param <T3> Type of the 3rd resource.
* @return a new {@link WithThreadedResources3} instance.
*/
public static <T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends AutoCloseable> WithThreadedResources3<T1, T2, T3> withResources(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function, CheckedFunction1<T2, ? extends T3> t3Function) {
return new WithThreadedResources3<>(t1Supplier, t2Function, t3Function);
}

/**
* Creates a {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
*
Expand Down Expand Up @@ -1565,6 +1593,39 @@ public <R> Try<R> of(CheckedFunction2<? super T1, ? super T2, ? extends R> f) {
}
}

/**
* A {@code Try}-with-resources builder that operates on two {@link AutoCloseable} threaded (dependent) resources.
*
* @param <T1> Type of the 1st resource.
* @param <T2> Type of the 2nd resource.
*/
public static final class WithThreadedResources2<T1 extends AutoCloseable, T2 extends AutoCloseable> {

private final CheckedFunction0<? extends T1> t1Supplier;
private final CheckedFunction1<T1, ? extends T2> t2Function;

private WithThreadedResources2(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
this.t1Supplier = t1Supplier;
this.t2Function = t2Function;
}

/**
* Wraps the result of a computation that may fail in a {@code Try}.
*
* @param f A computation that takes two {@code AutoClosable} resources.
* @param <R> Result type of the computation.
* @return A new {@code Try} instance.
*/
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
public <R> Try<R> of(CheckedFunction1<? super T2, ? extends R> f) {
return Try.of(() -> {
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1)) {
return f.apply(t2);
}
});
}
}

/**
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
*
Expand Down Expand Up @@ -1601,6 +1662,42 @@ public <R> Try<R> of(CheckedFunction3<? super T1, ? super T2, ? super T3, ? exte
}
}

/**
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} threaded (dependent) resources.
*
* @param <T1> Type of the 1st resource.
* @param <T2> Type of the 2nd resource.
* @param <T3> Type of the 3rd resource.
*/
public static final class WithThreadedResources3<T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends AutoCloseable> {

private final CheckedFunction0<? extends T1> t1Supplier;
private final CheckedFunction1<T1, ? extends T2> t2Function;
private final CheckedFunction1<T2, ? extends T3> t3Function;

private WithThreadedResources3(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function, CheckedFunction1<T2, ? extends T3> t3Function) {
this.t1Supplier = t1Supplier;
this.t2Function = t2Function;
this.t3Function = t3Function;
}

/**
* Wraps the result of a computation that may fail in a {@code Try}.
*
* @param f A computation that takes three {@code AutoClosable} resources.
* @param <R> Result type of the computation.
* @return A new {@code Try} instance.
*/
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
public <R> Try<R> of(CheckedFunction1<? super T3, ? extends R> f) {
return Try.of(() -> {
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1); T3 t3 = t3Function.apply(t2)) {
return f.apply(t3);
}
});
}
}

/**
* A {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
*
Expand Down
44 changes: 44 additions & 0 deletions src/test/java/io/vavr/control/TryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,50 @@ public void shouldCreateFailureTryWithResources8() {
assertThat(closeable8.isClosed).isTrue();
}

@Test
public void shouldCreateSuccessTryWithThreadedResources2() {
final Closeable<Integer> closeable1 = Closeable.of(1);
final Closeable<Integer> closeable2 = Closeable.of(2);
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> "" + i2.value);
assertThat(actual).isEqualTo(Success("2"));
assertThat(closeable1.isClosed).isTrue();
assertThat(closeable2.isClosed).isTrue();
}

@Test
public void shouldCreateFailureTryWithThreadedResources2() {
final Closeable<Integer> closeable1 = Closeable.of(1);
final Closeable<Integer> closeable2 = Closeable.of(2);
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> { throw new Error(); });
assertThat(actual.isFailure()).isTrue();
assertThat(closeable1.isClosed).isTrue();
assertThat(closeable2.isClosed).isTrue();
}

@Test
public void shouldCreateSuccessTryWithChainedResources3() {
final Closeable<Integer> closeable1 = Closeable.of(1);
final Closeable<Integer> closeable2 = Closeable.of(2);
final Closeable<Integer> closeable3 = Closeable.of(3);
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> "" + i3.value);
assertThat(actual).isEqualTo(Success("3"));
assertThat(closeable1.isClosed).isTrue();
assertThat(closeable2.isClosed).isTrue();
assertThat(closeable3.isClosed).isTrue();
}

@Test
public void shouldCreateFailureTryWithThreadedResources3() {
final Closeable<Integer> closeable1 = Closeable.of(1);
final Closeable<Integer> closeable2 = Closeable.of(2);
final Closeable<Integer> closeable3 = Closeable.of(3);
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> { throw new Error(); });
assertThat(actual.isFailure()).isTrue();
assertThat(closeable1.isClosed).isTrue();
assertThat(closeable2.isClosed).isTrue();
assertThat(closeable3.isClosed).isTrue();
}

// -- Failure.Cause

@Test(expected = InterruptedException.class)
Expand Down