Skip to content

Commit

Permalink
added JKScope withResource and letWithResource static methods
Browse files Browse the repository at this point in the history
  • Loading branch information
evpl committed Feb 18, 2024
1 parent 7aa946e commit 4af5517
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 3 deletions.
50 changes: 47 additions & 3 deletions src/main/java/com/plugatar/jkscope/JKScope.java
Expand Up @@ -293,6 +293,27 @@ static void withDouble(final double value,
block.asUnchecked().accept(value);
}

/**
* Performs given function block on given {@link AutoCloseable} value and close this value.
* <pre>{@code
* with(new MyResource(), it -> System.out.println(it.getValue()));
* }</pre>
*
* @param value the value
* @param block the function block
* @param <V> the type of the value
* @throws NullPointerException if {@code block} arg is null
*/
static <V extends AutoCloseable> void withResource(final V value,
final ThConsumer<? super V, ?> block) {
blockArgNotNull(block);
((ThBiConsumer<V, ThConsumer<? super V, ?>, Throwable>) (v, b) -> {
try (final V resource = v) {
b.accept(resource);
}
}).asUnchecked().accept(value, block);
}

/**
* Performs given function block on given values.
* <pre>{@code
Expand Down Expand Up @@ -623,9 +644,9 @@ static double letDoubleRec(final double initialValue,
/**
* Performs given function block on given value and returns result.
* <pre>{@code
* String value = letWith("Hi", (str) -> {
* System.out.println(str);
* return "Oh " + str + " Mark";
* String value = letWith("Hi", it -> {
* System.out.println(it);
* return "Oh " + it + " Mark";
* });
* }</pre>
*
Expand All @@ -642,6 +663,29 @@ static <V, R> R letWith(final V value,
return block.asUnchecked().apply(value);
}

/**
* Performs given function block on {@link AutoCloseable} value, close this value and returns result.
* <pre>{@code
* String value = letWith(new MyResource(), it -> it.getValue());
* }</pre>
*
* @param value the value
* @param block the function block
* @param <V> the type of the value
* @param <R> the type of the result
* @return result
* @throws NullPointerException if {@code block} arg is null
*/
static <V extends AutoCloseable, R> R letWithResource(final V value,
final ThFunction<? super V, ? extends R, ?> block) {
blockArgNotNull(block);
return ((ThBiFunction<V, ThFunction<? super V, ? extends R, ?>, R, Throwable>) (v, b) -> {
try (final V resource = v) {
return b.apply(resource);
}
}).asUnchecked().apply(value, block);
}

/**
* Performs given function block on given value and returns result.
* <pre>{@code
Expand Down
86 changes: 86 additions & 0 deletions src/test/java/com/plugatar/jkscope/JKScopeTest.java
Expand Up @@ -327,6 +327,15 @@ void withDoubleStaticMethodThrowsNPEForNullArg() {
.isInstanceOf(NullPointerException.class);
}

@Test
void withResourceMethodThrowsNPEForNullArg() {
final AutoCloseable value = new AutoCloseableImpl();
final ThConsumer<Object, Throwable> block = null;

assertThatThrownBy(() -> JKScope.withResource(value, block))
.isInstanceOf(NullPointerException.class);
}

@Test
void with2ArgsStaticMethodThrowsNPEForNullArg() {
final Object value1 = new Object();
Expand Down Expand Up @@ -461,6 +470,15 @@ void letWithStaticMethodThrowsNPEForNullArg() {
.isInstanceOf(NullPointerException.class);
}

@Test
void letWithResourceMethodThrowsNPEForNullArg() {
final AutoCloseable value = new AutoCloseableImpl();
final ThFunction<Object, Object, Throwable> block = null;

assertThatThrownBy(() -> JKScope.letWithResource(value, block))
.isInstanceOf(NullPointerException.class);
}

@Test
void letWith2ArgsStaticMethodThrowsNPEForNullArg() {
final Object value1 = new Object();
Expand Down Expand Up @@ -628,6 +646,31 @@ void withDoubleStaticMethodThrowsException() {
.isSameAs(throwable);
}

@Test
void withResourceMethod() {
final AutoCloseableImpl value = new AutoCloseableImpl();
final AtomicReference<Object> valueRef = new AtomicReference<>();
final ThConsumer<Object, Throwable> block = arg -> valueRef.set(arg);

JKScope.withResource(value, block);
assertThat(valueRef.get())
.isSameAs(value);
assertThat(value.isClosed())
.isTrue();
}

@Test
void withResourceMethodThrowsException() {
final AutoCloseableImpl value = new AutoCloseableImpl();
final Throwable throwable = new Throwable();
final ThConsumer<Object, Throwable> block = arg -> { throw throwable; };

assertThatThrownBy(() -> JKScope.withResource(value, block))
.isSameAs(throwable);
assertThat(value.isClosed())
.isTrue();
}

@Test
void with2ArgsStaticMethod() {
final Object value1 = new Object();
Expand Down Expand Up @@ -1052,6 +1095,36 @@ void letWithStaticMethodThrowsException() {
.isSameAs(throwable);
}

@Test
void letWithResourceMethod() {
final AutoCloseableImpl value = new AutoCloseableImpl();
final Object result = new Object();
final AtomicReference<Object> valueRef = new AtomicReference<>();
final ThFunction<Object, Object, Throwable> block = arg -> {
valueRef.set(arg);
return result;
};

assertThat(JKScope.letWithResource(value, block))
.isSameAs(result);
assertThat(valueRef.get())
.isSameAs(value);
assertThat(value.isClosed())
.isTrue();
}

@Test
void letWithResourceMethodThrowsException() {
final AutoCloseableImpl value = new AutoCloseableImpl();
final Throwable throwable = new Throwable();
final ThFunction<Object, Object, Throwable> block = arg -> { throw throwable; };

assertThatThrownBy(() -> JKScope.letWithResource(value, block))
.isSameAs(throwable);
assertThat(value.isClosed())
.isTrue();
}

@Test
void letWith2ArgsStaticMethod() {
final Object value1 = new Object();
Expand Down Expand Up @@ -1126,4 +1199,17 @@ void letWith3ArgsStaticMethodThrowsException() {

private static final class Impl implements JKScope<Impl> {
}

private static final class AutoCloseableImpl implements AutoCloseable {
private boolean isClosed = false;

@Override
public void close() throws Exception {
this.isClosed = true;
}

public boolean isClosed() {
return this.isClosed;
}
}
}

0 comments on commit 4af5517

Please sign in to comment.