From 10b19a3cab7d7f2a39f9e8bdc41c9785f1001be8 Mon Sep 17 00:00:00 2001 From: mohamedsamehsalah Date: Sun, 3 Nov 2024 11:07:44 +0100 Subject: [PATCH] Introduce `Mono#using{When}` reactor refaster rules --- .../refasterrules/ReactorRules.java | 139 ++++++++++++++++++ .../refasterrules/ReactorRulesTestInput.java | 34 +++++ .../refasterrules/ReactorRulesTestOutput.java | 30 ++++ 3 files changed, 203 insertions(+) diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java index 12c4f39d..7012f950 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java @@ -548,6 +548,145 @@ final class ReactorRules { } } + /** + * Don't unnecessarily transform a {@link Flux#using(Callable, Function)} to a mono, instead use + * the equivalent API provided by {@link Mono}. + */ + static final class MonoUsing< + D extends AutoCloseable, T, P extends Publisher, M extends Mono> { + @BeforeTemplate + Mono before(Callable resourceSupplier, Function sourceSupplier) { + return Flux.using(resourceSupplier, sourceSupplier).single(); + } + + @AfterTemplate + Mono after(Callable resourceSupplier, Function sourceSupplier) { + return Mono.using(resourceSupplier, sourceSupplier); + } + } + + /** + * Don't unnecessarily transform a {@link Flux#using(Callable, Function, boolean)} to a mono, + * instead use the equivalent API provided by {@link Mono}. + */ + static final class MonoUsingEager< + D extends AutoCloseable, T, P extends Publisher, M extends Mono> { + @BeforeTemplate + Mono before(Callable resourceSupplier, Function sourceSupplier, boolean eager) { + return Flux.using(resourceSupplier, sourceSupplier, eager).single(); + } + + @AfterTemplate + Mono after(Callable resourceSupplier, Function sourceSupplier, boolean eager) { + return Mono.using(resourceSupplier, sourceSupplier, eager); + } + } + + /** + * Don't unnecessarily transform a {@link Flux#using(Callable, Function, Consumer)} to a mono, + * instead use the equivalent API provided by {@link Mono}. + */ + static final class MonoUsing2< + D, T, P extends Publisher, M extends Mono> { + @BeforeTemplate + Mono before( + Callable resourceSupplier, Function sourceSupplier, Consumer resourceCleanup) { + return Flux.using(resourceSupplier, sourceSupplier, resourceCleanup).single(); + } + + @AfterTemplate + Mono after( + Callable resourceSupplier, Function sourceSupplier, Consumer resourceCleanup) { + return Mono.using(resourceSupplier, sourceSupplier, resourceCleanup); + } + } + + /** + * Don't unnecessarily transform a {@link Flux#using(Callable, Function, Consumer, boolean)} to a + * mono, instead use the equivalent API provided by {@link Mono}. + */ + static final class MonoUsing2Eager< + D, T, P extends Publisher, M extends Mono> { + @BeforeTemplate + Mono before( + Callable resourceSupplier, + Function sourceSupplier, + Consumer resourceCleanup, + boolean eager) { + return Flux.using(resourceSupplier, sourceSupplier, resourceCleanup, eager).single(); + } + + @AfterTemplate + Mono after( + Callable resourceSupplier, + Function sourceSupplier, + Consumer resourceCleanup, + boolean eager) { + return Mono.using(resourceSupplier, sourceSupplier, resourceCleanup, eager); + } + } + + /** + * Don't unnecessarily transform a {@link Flux#usingWhen(Publisher, Function, Function)} to a + * mono, instead use the equivalent API provided by {@link Mono}. + */ + static final class MonoUsingWhen< + D, + T, + P extends Publisher, + P2 extends Publisher, + M extends Mono> { + @BeforeTemplate + Mono before( + Publisher resourceSupplier, + Function resourceClosure, + Function asyncCleanup) { + return Flux.usingWhen(resourceSupplier, resourceClosure, asyncCleanup).single(); + } + + @AfterTemplate + Mono after( + Publisher resourceSupplier, + Function resourceClosure, + Function asyncCleanup) { + return Mono.usingWhen(resourceSupplier, resourceClosure, asyncCleanup); + } + } + + /** + * Don't unnecessarily transform a {@link Flux#usingWhen(Publisher, Function, Function, + * BiFunction, Function)} to a mono, instead use the equivalent API provided by {@link Mono}. + */ + static final class MonoUsingWhen2< + D, + T, + P extends Publisher, + P2 extends Publisher, + M extends Mono> { + @BeforeTemplate + Mono before( + Publisher resourceSupplier, + Function resourceClosure, + Function asyncComplete, + BiFunction asyncError, + Function asyncCancel) { + return Flux.usingWhen( + resourceSupplier, resourceClosure, asyncComplete, asyncError, asyncCancel) + .single(); + } + + @AfterTemplate + Mono after( + Publisher resourceSupplier, + Function resourceClosure, + Function asyncComplete, + BiFunction> asyncError, + Function asyncCancel) { + return Mono.usingWhen( + resourceSupplier, resourceClosure, asyncComplete, asyncError, asyncCancel); + } + } + /** Don't unnecessarily pass an empty publisher to {@link Flux#switchIfEmpty(Publisher)}. */ static final class FluxSwitchIfEmptyOfEmptyPublisher { @BeforeTemplate diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java index b87e5783..046aba19 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java @@ -15,6 +15,7 @@ import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import java.io.ByteArrayInputStream; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; @@ -210,6 +211,39 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { return Mono.just(1).flux().single(); } + Mono testMonoUsing() { + return Flux.using(() -> new ByteArrayInputStream(new byte[] {}), s -> Mono.just("foo")) + .single(); + } + + Mono testMonoUsingEager() { + return Flux.using(() -> new ByteArrayInputStream(new byte[] {}), s -> Mono.just("foo"), false) + .single(); + } + + Mono testMonoUsing2() { + return Flux.using(() -> "foo", foo -> Mono.just("bar"), foo -> {}).single(); + } + + Mono testMonoUsing2Eager() { + return Flux.using(() -> "foo", foo -> Mono.just("bar"), foo -> {}, false).single(); + } + + Mono testMonoUsingWhen() { + return Flux.usingWhen(Mono.just("foo"), foo -> Mono.just("bar"), foo -> Mono.just("baz")) + .single(); + } + + Mono testMonoUsingWhen2() { + return Flux.usingWhen( + Mono.just("foo"), + foo -> Mono.just("bar"), + foo -> Mono.just("baz"), + (foo, e) -> Mono.just("qux"), + foo -> Mono.just("thud")) + .single(); + } + ImmutableSet> testFluxSwitchIfEmptyOfEmptyPublisher() { return ImmutableSet.of( Flux.just(1).switchIfEmpty(Mono.empty()), Flux.just(2).switchIfEmpty(Flux.empty())); diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java index 4aa24950..b0577fc7 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java @@ -17,6 +17,7 @@ import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import java.io.ByteArrayInputStream; import java.time.Duration; import java.util.ArrayList; import java.util.Collection; @@ -209,6 +210,35 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { return Mono.just(1).single(); } + Mono testMonoUsing() { + return Mono.using(() -> new ByteArrayInputStream(new byte[] {}), s -> Mono.just("foo")); + } + + Mono testMonoUsingEager() { + return Mono.using(() -> new ByteArrayInputStream(new byte[] {}), s -> Mono.just("foo"), false); + } + + Mono testMonoUsing2() { + return Mono.using(() -> "foo", foo -> Mono.just("bar"), foo -> {}); + } + + Mono testMonoUsing2Eager() { + return Mono.using(() -> "foo", foo -> Mono.just("bar"), foo -> {}, false); + } + + Mono testMonoUsingWhen() { + return Mono.usingWhen(Mono.just("foo"), foo -> Mono.just("bar"), foo -> Mono.just("baz")); + } + + Mono testMonoUsingWhen2() { + return Mono.usingWhen( + Mono.just("foo"), + foo -> Mono.just("bar"), + foo -> Mono.just("baz"), + (foo, e) -> Mono.just("qux"), + foo -> Mono.just("thud")); + } + ImmutableSet> testFluxSwitchIfEmptyOfEmptyPublisher() { return ImmutableSet.of(Flux.just(1), Flux.just(2)); }