Skip to content

Commit c3d060c

Browse files
thinstripepivovarit
authored andcommitted
Add support for threaded use of Try.withResources() for up to 3 arguments.
3 arguments is probably enough to cover common scenarios/use cases such as database related resource management (Connection, PreparedStatement, ResultSet).
1 parent 58698b7 commit c3d060c

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

src/main/java/io/vavr/control/Try.java

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,19 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithResources
13981398
return new WithResources2<>(t1Supplier, t2Supplier);
13991399
}
14001400

1401+
/**
1402+
* Creates a {@code Try}-with-resources builder that operates on two {@link AutoCloseable} chained (dependent) resources.
1403+
*
1404+
* @param t1Supplier The supplier of the 1st resource.
1405+
* @param t2Function A function which takes the supply of t1 and supplies the 2nd resource.
1406+
* @param <T1> Type of the 1st resource.
1407+
* @param <T2> Type of the 2nd resource.
1408+
* @return a new {@link WithThreadedResources2} instance.
1409+
*/
1410+
public static <T1 extends AutoCloseable, T2 extends AutoCloseable> WithThreadedResources2<T1, T2> withResources(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
1411+
return new WithThreadedResources2<>(t1Supplier, t2Function);
1412+
}
1413+
14011414
/**
14021415
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
14031416
*
@@ -1413,6 +1426,21 @@ public static <T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends Au
14131426
return new WithResources3<>(t1Supplier, t2Supplier, t3Supplier);
14141427
}
14151428

1429+
/**
1430+
* Creates a {@code Try}-with-resources builder that operates on three {@link AutoCloseable} chained (dependent) resources.
1431+
*
1432+
* @param t1Supplier The supplier of the 1st resource.
1433+
* @param t2Function A function which takes a supply of the 1st resource and supplies the 2nd resource.
1434+
* @param t3Function A function which takes a supply of the 2nd resource and supplies the 3rd resource.
1435+
* @param <T1> Type of the 1st resource.
1436+
* @param <T2> Type of the 2nd resource.
1437+
* @param <T3> Type of the 3rd resource.
1438+
* @return a new {@link WithThreadedResources3} instance.
1439+
*/
1440+
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) {
1441+
return new WithThreadedResources3<>(t1Supplier, t2Function, t3Function);
1442+
}
1443+
14161444
/**
14171445
* Creates a {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
14181446
*
@@ -1581,6 +1609,39 @@ public <R> Try<R> of(CheckedFunction2<? super T1, ? super T2, ? extends R> f) {
15811609
}
15821610
}
15831611

1612+
/**
1613+
* A {@code Try}-with-resources builder that operates on two {@link AutoCloseable} threaded (dependent) resources.
1614+
*
1615+
* @param <T1> Type of the 1st resource.
1616+
* @param <T2> Type of the 2nd resource.
1617+
*/
1618+
public static final class WithThreadedResources2<T1 extends AutoCloseable, T2 extends AutoCloseable> {
1619+
1620+
private final CheckedFunction0<? extends T1> t1Supplier;
1621+
private final CheckedFunction1<T1, ? extends T2> t2Function;
1622+
1623+
private WithThreadedResources2(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function) {
1624+
this.t1Supplier = t1Supplier;
1625+
this.t2Function = t2Function;
1626+
}
1627+
1628+
/**
1629+
* Wraps the result of a computation that may fail in a {@code Try}.
1630+
*
1631+
* @param f A computation that takes two {@code AutoClosable} resources.
1632+
* @param <R> Result type of the computation.
1633+
* @return A new {@code Try} instance.
1634+
*/
1635+
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
1636+
public <R> Try<R> of(CheckedFunction1<? super T2, ? extends R> f) {
1637+
return Try.of(() -> {
1638+
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1)) {
1639+
return f.apply(t2);
1640+
}
1641+
});
1642+
}
1643+
}
1644+
15841645
/**
15851646
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} resources.
15861647
*
@@ -1617,6 +1678,42 @@ public <R> Try<R> of(CheckedFunction3<? super T1, ? super T2, ? super T3, ? exte
16171678
}
16181679
}
16191680

1681+
/**
1682+
* A {@code Try}-with-resources builder that operates on three {@link AutoCloseable} threaded (dependent) resources.
1683+
*
1684+
* @param <T1> Type of the 1st resource.
1685+
* @param <T2> Type of the 2nd resource.
1686+
* @param <T3> Type of the 3rd resource.
1687+
*/
1688+
public static final class WithThreadedResources3<T1 extends AutoCloseable, T2 extends AutoCloseable, T3 extends AutoCloseable> {
1689+
1690+
private final CheckedFunction0<? extends T1> t1Supplier;
1691+
private final CheckedFunction1<T1, ? extends T2> t2Function;
1692+
private final CheckedFunction1<T2, ? extends T3> t3Function;
1693+
1694+
private WithThreadedResources3(CheckedFunction0<? extends T1> t1Supplier, CheckedFunction1<T1, ? extends T2> t2Function, CheckedFunction1<T2, ? extends T3> t3Function) {
1695+
this.t1Supplier = t1Supplier;
1696+
this.t2Function = t2Function;
1697+
this.t3Function = t3Function;
1698+
}
1699+
1700+
/**
1701+
* Wraps the result of a computation that may fail in a {@code Try}.
1702+
*
1703+
* @param f A computation that takes three {@code AutoClosable} resources.
1704+
* @param <R> Result type of the computation.
1705+
* @return A new {@code Try} instance.
1706+
*/
1707+
@SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */
1708+
public <R> Try<R> of(CheckedFunction1<? super T3, ? extends R> f) {
1709+
return Try.of(() -> {
1710+
try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Function.apply(t1); T3 t3 = t3Function.apply(t2)) {
1711+
return f.apply(t3);
1712+
}
1713+
});
1714+
}
1715+
}
1716+
16201717
/**
16211718
* A {@code Try}-with-resources builder that operates on four {@link AutoCloseable} resources.
16221719
*

src/test/java/io/vavr/control/TryTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,50 @@ public void shouldCreateFailureTryWithResources8() {
627627
assertThat(closeable8.isClosed).isTrue();
628628
}
629629

630+
@Test
631+
public void shouldCreateSuccessTryWithThreadedResources2() {
632+
final Closeable<Integer> closeable1 = Closeable.of(1);
633+
final Closeable<Integer> closeable2 = Closeable.of(2);
634+
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> "" + i2.value);
635+
assertThat(actual).isEqualTo(Success("2"));
636+
assertThat(closeable1.isClosed).isTrue();
637+
assertThat(closeable2.isClosed).isTrue();
638+
}
639+
640+
@Test
641+
public void shouldCreateFailureTryWithThreadedResources2() {
642+
final Closeable<Integer> closeable1 = Closeable.of(1);
643+
final Closeable<Integer> closeable2 = Closeable.of(2);
644+
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2).of(i2 -> { throw new Error(); });
645+
assertThat(actual.isFailure()).isTrue();
646+
assertThat(closeable1.isClosed).isTrue();
647+
assertThat(closeable2.isClosed).isTrue();
648+
}
649+
650+
@Test
651+
public void shouldCreateSuccessTryWithChainedResources3() {
652+
final Closeable<Integer> closeable1 = Closeable.of(1);
653+
final Closeable<Integer> closeable2 = Closeable.of(2);
654+
final Closeable<Integer> closeable3 = Closeable.of(3);
655+
final Try<String> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> "" + i3.value);
656+
assertThat(actual).isEqualTo(Success("3"));
657+
assertThat(closeable1.isClosed).isTrue();
658+
assertThat(closeable2.isClosed).isTrue();
659+
assertThat(closeable3.isClosed).isTrue();
660+
}
661+
662+
@Test
663+
public void shouldCreateFailureTryWithThreadedResources3() {
664+
final Closeable<Integer> closeable1 = Closeable.of(1);
665+
final Closeable<Integer> closeable2 = Closeable.of(2);
666+
final Closeable<Integer> closeable3 = Closeable.of(3);
667+
final Try<?> actual = Try.withResources(() -> closeable1, i1 -> closeable2, i2 -> closeable3).of(i3 -> { throw new Error(); });
668+
assertThat(actual.isFailure()).isTrue();
669+
assertThat(closeable1.isClosed).isTrue();
670+
assertThat(closeable2.isClosed).isTrue();
671+
assertThat(closeable3.isClosed).isTrue();
672+
}
673+
630674
// -- Failure.Cause
631675

632676
@Test

0 commit comments

Comments
 (0)