Skip to content

Commit

Permalink
fix(core): Generic types bounds (#220)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseLion committed Nov 9, 2023
1 parent 37500b1 commit 6fdf740
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 104 deletions.
20 changes: 10 additions & 10 deletions src/main/java/io/github/joselion/maybe/EffectHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public EffectHandler<E> doOnSuccess(final Runnable effect) {
* @param effect a consumer function that recieves the caught error
* @return the same handler to continue chainning operations
*/
public <X extends Throwable> EffectHandler<E> doOnError(final Class<X> ofType, final Consumer<X> effect) {
public <X extends Throwable> EffectHandler<E> doOnError(final Class<X> ofType, final Consumer<? super X> effect) {
this.error
.filter(ofType::isInstance)
.map(ofType::cast)
Expand All @@ -98,7 +98,7 @@ public <X extends Throwable> EffectHandler<E> doOnError(final Class<X> ofType, f
* @param effect a consumer function that recieves the caught error
* @return the same handler to continue chainning operations
*/
public EffectHandler<E> doOnError(final Consumer<E> effect) {
public EffectHandler<E> doOnError(final Consumer<? super E> effect) {
this.error.ifPresent(effect);

return this;
Expand All @@ -116,7 +116,7 @@ public EffectHandler<E> doOnError(final Consumer<E> effect) {
* @return an empty handler if an error instance of the provided type was
* caught. The same handler instance otherwise
*/
public <X extends E> EffectHandler<E> catchError(final Class<X> ofType, final Consumer<X> handler) {
public <X extends Throwable> EffectHandler<E> catchError(final Class<X> ofType, final Consumer<? super X> handler) {
return this.error
.filter(ofType::isInstance)
.map(ofType::cast)
Expand All @@ -137,7 +137,7 @@ public <X extends E> EffectHandler<E> catchError(final Class<X> ofType, final Co
* @return an empty handler if the error is present. The same handler
* instance otherwise
*/
public EffectHandler<E> catchError(final Consumer<E> handler) {
public EffectHandler<E> catchError(final Consumer<? super E> handler) {
return this.error
.map(caught -> {
handler.accept(caught);
Expand All @@ -157,11 +157,11 @@ public EffectHandler<E> catchError(final Consumer<E> handler) {
* invoked callback
*/
public <X extends Throwable> EffectHandler<X> runEffect(
final ThrowingRunnable<X> onSuccess,
final ThrowingConsumer<E, X> onError
final ThrowingRunnable<? extends X> onSuccess,
final ThrowingConsumer<? super E, ? extends X> onError
) {
return this.error
.map(Maybe.partialEffect(onError))
.map(Maybe.<E, X>partialEffect(onError))
.orElseGet(() -> Maybe.fromEffect(onSuccess));
}

Expand All @@ -175,7 +175,7 @@ public <X extends Throwable> EffectHandler<X> runEffect(
* @return a new {@link EffectHandler} that is either empty or with the
* thrown error
*/
public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingRunnable<X> effect) {
public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingRunnable<? extends X> effect) {
return this.runEffect(effect, err -> { });
}

Expand All @@ -185,7 +185,7 @@ public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingRunnable<X
*
* @param effect a consumer function that receives the caught error
*/
public void orElse(final Consumer<E> effect) {
public void orElse(final Consumer<? super E> effect) {
this.error.ifPresent(effect);
}

Expand All @@ -208,7 +208,7 @@ public void orThrow() throws E {
* @param mapper a function that maps the new exception to throw
* @throws X a mapped exception
*/
public <X extends Throwable> void orThrow(final Function<E, X> mapper) throws X {
public <X extends Throwable> void orThrow(final Function<? super E, ? extends X> mapper) throws X {
if (this.error.isPresent()) {
throw mapper.apply(this.error.get());
}
Expand Down
29 changes: 17 additions & 12 deletions src/main/java/io/github/joselion/maybe/Maybe.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ public static <T> Maybe<T> fromOptional(final Optional<T> value) {
* @return a {@link ResolveHandler} with either the value resolved or the thrown
* exception to be handled
*/
public static <T, E extends Throwable> ResolveHandler<T, E> fromResolver(final ThrowingSupplier<T, E> resolver) {
public static <T, E extends Throwable> ResolveHandler<T, E> fromResolver(
final ThrowingSupplier<? extends T, ? extends E> resolver
) {
try {
return ResolveHandler.ofSuccess(resolver.get());
} catch (Throwable e) { // NOSONAR
Expand All @@ -116,7 +118,7 @@ public static <T, E extends Throwable> ResolveHandler<T, E> fromResolver(final T
* @return an {@link EffectHandler} with either the thrown exception to be
* handled or nothing
*/
public static <E extends Throwable> EffectHandler<E> fromEffect(final ThrowingRunnable<E> effect) {
public static <E extends Throwable> EffectHandler<E> fromEffect(final ThrowingRunnable<? extends E> effect) {
try {
effect.run();
return EffectHandler.empty();
Expand Down Expand Up @@ -153,7 +155,7 @@ public static <E extends Throwable> EffectHandler<E> fromEffect(final ThrowingRu
* that receives an {@code S} value, and produces a {@code ResolveHandler<T, E>}
*/
public static <S, T, E extends Throwable> Function<S, ResolveHandler<T, E>> partialResolver(
final ThrowingFunction<S, T, E> resolver
final ThrowingFunction<? super S, ? extends T, ? extends E> resolver
) {
return value -> Maybe.fromResolver(() -> resolver.apply(value));
}
Expand Down Expand Up @@ -183,7 +185,7 @@ public static <S, T, E extends Throwable> Function<S, ResolveHandler<T, E>> part
* that receives an {@code S} value, and produces an {@code EffectHandler<E>}
*/
public static <S, E extends Throwable> Function<S, EffectHandler<E>> partialEffect(
final ThrowingConsumer<S, E> effect
final ThrowingConsumer<? super S, ? extends E> effect
) {
return value -> Maybe.fromEffect(() -> effect.accept(value));
}
Expand Down Expand Up @@ -217,7 +219,7 @@ public static <R extends AutoCloseable, E extends Throwable> ResourceHolder<R, E
* or run an effect using the prepared resource
*/
public static <R extends Closeable, E extends Throwable> ResourceHolder<R, E> solveResource(
final ThrowingSupplier<R, E> supplier
final ThrowingSupplier<? extends R, ? extends E> supplier
) {
return Maybe
.fromResolver(supplier)
Expand All @@ -234,10 +236,10 @@ public static <R extends Closeable, E extends Throwable> ResourceHolder<R, E> so
* @return a {@code Maybe} with the mapped value if present,
* {@link #nothing()} otherwise
*/
public <U> Maybe<U> map(final Function<T, U> mapper) {
public <U> Maybe<U> map(final Function<? super T, ? extends U> mapper) {
return Maybe
.fromOptional(this.value)
.resolve(mapper::apply)
.<U, Throwable>resolve(mapper::apply)
.toMaybe();
}

Expand All @@ -254,10 +256,11 @@ public <U> Maybe<U> map(final Function<T, U> mapper) {
* @return a {@code Maybe} with the mapped value if present,
* {@link #nothing()} otherwise
*/
public <U> Maybe<U> flatMap(final Function<T, Maybe<U>> mapper) {
public <U> Maybe<U> flatMap(final Function<? super T, Maybe<? extends U>> mapper) {
return Maybe
.fromOptional(this.value)
.resolve(mapper::apply)
.map(Commons::<Maybe<U>>cast)
.orElseGet(Maybe::nothing);
}

Expand All @@ -273,10 +276,12 @@ public <U> Maybe<U> flatMap(final Function<T, Maybe<U>> mapper) {
* @return a {@link ResolveHandler} with either the resolved value, or the
* thrown exception to be handled
*/
public <U, E extends Throwable> ResolveHandler<U, E> resolve(final ThrowingFunction<T, U, E> resolver) {
public <U, E extends Throwable> ResolveHandler<U, E> resolve(
final ThrowingFunction<? super T, ? extends U, ? extends E> resolver
) {
try {
return this.value
.map(Maybe.partialResolver(resolver))
.map(Maybe.<T, U, E>partialResolver(resolver))
.orElseThrow();
} catch (final NoSuchElementException e) {
final var error = Commons.<E>cast(e);
Expand All @@ -293,10 +298,10 @@ public <U, E extends Throwable> ResolveHandler<U, E> resolve(final ThrowingFunct
* @return an {@link EffectHandler} with either the thrown exception to be
* handled or nothing
*/
public <E extends Throwable> EffectHandler<E> runEffect(final ThrowingConsumer<T, E> effect) {
public <E extends Throwable> EffectHandler<E> runEffect(final ThrowingConsumer<? super T, ? extends E> effect) {
try {
return this.value
.map(Maybe.partialEffect(effect))
.map(Maybe.<T, E>partialEffect(effect))
.orElseThrow();
} catch (final NoSuchElementException e) {
final var error = Commons.<E>cast(e);
Expand Down
37 changes: 21 additions & 16 deletions src/main/java/io/github/joselion/maybe/ResolveHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Optional<E> error() {
* @param effect a function that receives the resolved value
* @return the same handler to continue chainning operations
*/
public ResolveHandler<T, E> doOnSuccess(final Consumer<T> effect) {
public ResolveHandler<T, E> doOnSuccess(final Consumer<? super T> effect) {
this.value.doOnRight(effect);

return this;
Expand All @@ -96,7 +96,7 @@ public ResolveHandler<T, E> doOnSuccess(final Consumer<T> effect) {
* @param effect a consumer function that receives the caught error
* @return the same handler to continue chainning operations
*/
public <X extends Throwable> ResolveHandler<T, E> doOnError(final Class<X> ofType, final Consumer<X> effect) {
public <X extends Throwable> ResolveHandler<T, E> doOnError(final Class<X> ofType, final Consumer<? super X> effect) {
this.value
.leftToOptional()
.filter(ofType::isInstance)
Expand All @@ -113,7 +113,7 @@ public <X extends Throwable> ResolveHandler<T, E> doOnError(final Class<X> ofTyp
* @param effect a consumer function that receives the caught error
* @return the same handler to continue chainning operations
*/
public ResolveHandler<T, E> doOnError(final Consumer<E> effect) {
public ResolveHandler<T, E> doOnError(final Consumer<? super E> effect) {
this.value.doOnLeft(effect);

return this;
Expand All @@ -131,7 +131,10 @@ public ResolveHandler<T, E> doOnError(final Consumer<E> effect) {
* @return a handler containing a new value if an error instance of the
* provided type was caught. The same handler instance otherwise
*/
public <X extends E> ResolveHandler<T, E> catchError(final Class<X> ofType, final Function<X, T> handler) {
public <X extends Throwable> ResolveHandler<T, E> catchError(
final Class<X> ofType,
final Function<? super X, ? extends T> handler
) {
return this.value
.leftToOptional()
.filter(ofType::isInstance)
Expand All @@ -150,7 +153,7 @@ public <X extends E> ResolveHandler<T, E> catchError(final Class<X> ofType, fina
* @return a handler containing a new value if an error was caught. The same
* handler instance otherwise
*/
public ResolveHandler<T, E> catchError(final Function<E, T> handler) {
public ResolveHandler<T, E> catchError(final Function<? super E, ? extends T> handler) {
return this.value
.mapLeft(handler)
.mapLeft(ResolveHandler::<T, E>ofSuccess)
Expand All @@ -175,8 +178,8 @@ public ResolveHandler<T, E> catchError(final Function<E, T> handler) {
* @return a new handler with either the resolved value or the error
*/
public <S, X extends Throwable> ResolveHandler<S, X> resolve(
final ThrowingFunction<T, S, X> onSuccess,
final ThrowingFunction<E, S, X> onError
final ThrowingFunction<? super T, ? extends S, ? extends X> onSuccess,
final ThrowingFunction<? super E, ? extends S, ? extends X> onError
) {
return this.value.unwrap(
Maybe.partialResolver(onError),
Expand All @@ -194,7 +197,9 @@ public <S, X extends Throwable> ResolveHandler<S, X> resolve(
* resolves another
* @return a new handler with either the resolved value or an error
*/
public <S, X extends Throwable> ResolveHandler<S, X> resolve(final ThrowingFunction<T, S, X> resolver) {
public <S, X extends Throwable> ResolveHandler<S, X> resolve(
final ThrowingFunction<? super T, ? extends S, ? extends X> resolver
) {
return this.value
.mapLeft(Commons::<X>cast)
.unwrap(
Expand All @@ -214,8 +219,8 @@ public <S, X extends Throwable> ResolveHandler<S, X> resolve(final ThrowingFunct
* invoked callback
*/
public <X extends Throwable> EffectHandler<X> runEffect(
final ThrowingConsumer<T, X> onSuccess,
final ThrowingConsumer<E, X> onError
final ThrowingConsumer<? super T, ? extends X> onSuccess,
final ThrowingConsumer<? super E, ? extends X> onError
) {
return this.value.unwrap(
Maybe.partialEffect(onError),
Expand All @@ -233,7 +238,7 @@ public <X extends Throwable> EffectHandler<X> runEffect(
* @return a new {@link EffectHandler} representing the result of the success
* callback or containg the error
*/
public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingConsumer<T, X> effect) {
public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingConsumer<? super T, ? extends X> effect) {
return this.value
.mapLeft(Commons::<X>cast)
.unwrap(
Expand All @@ -251,7 +256,7 @@ public <X extends Throwable> EffectHandler<X> runEffect(final ThrowingConsumer<T
* @param mapper a function that receives the resolved value and produces another
* @return a new handler with either the mapped value, or the previous error
*/
public <U> ResolveHandler<U, E> map(final Function<T, U> mapper) {
public <U> ResolveHandler<U, E> map(final Function<? super T, ? extends U> mapper) {
return this.value
.mapRight(mapper)
.unwrap(
Expand Down Expand Up @@ -302,7 +307,7 @@ public T orElse(final T fallback) {
* another value
* @return the resolved value if present. Another value otherwise
*/
public T orElse(final Function<E, T> mapper) {
public T orElse(final Function<? super E, ? extends T> mapper) {
return this.value.unwrap(mapper, Function.identity());
}

Expand All @@ -317,7 +322,7 @@ public T orElse(final Function<E, T> mapper) {
* opration failed to resolve
* @return the resolved value if present. Another value otherwise
*/
public T orElseGet(final Supplier<T> supplier) {
public T orElseGet(final Supplier<? extends T> supplier) {
return this.value
.rightToOptional()
.orElseGet(supplier);
Expand Down Expand Up @@ -360,7 +365,7 @@ public T orThrow() throws E {
* @return the resolved/handled value if present
* @throws X a mapped exception
*/
public <X extends Throwable> T orThrow(final Function<E, X> mapper) throws X {
public <X extends Throwable> T orThrow(final Function<? super E, ? extends X> mapper) throws X {
return this.value
.rightToOptional()
.orElseThrow(() -> mapper.apply(this.value.leftOrNull()));
Expand Down Expand Up @@ -444,7 +449,7 @@ public <R extends AutoCloseable> ResourceHolder<R, E> mapToResource(final Functi
* present or the error otherwise.
*/
public <R extends AutoCloseable, X extends Throwable> ResourceHolder<R, X> solveResource(
final ThrowingFunction<T, R, X> solver
final ThrowingFunction<? super T, ? extends R, ? extends X> solver
) {
return this.value
.mapLeft(Commons::<X>cast)
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/io/github/joselion/maybe/ResourceHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ Optional<E> error() {
* @return a {@link ResolveHandler} with either the value resolved or the thrown
* exception to be handled
*/
public <T, X extends Throwable> ResolveHandler<T, X> resolveClosing(final ThrowingFunction<R, T, X> resolver) {
public <T, X extends Throwable> ResolveHandler<T, X> resolveClosing(
final ThrowingFunction<? super R, ? extends T, ? extends X> resolver
) {
return this.value
.mapLeft(Commons::<X>cast)
.unwrap(
Expand Down Expand Up @@ -122,7 +124,9 @@ public <T, X extends Throwable> ResolveHandler<T, X> resolveClosing(final Throwi
* @return an {@link EffectHandler} with either the thrown exception to be
* handled or nothing
*/
public <X extends Throwable> EffectHandler<X> runEffectClosing(final ThrowingConsumer<R, X> effect) {
public <X extends Throwable> EffectHandler<X> runEffectClosing(
final ThrowingConsumer<? super R, ? extends X> effect
) {
return this.value
.mapLeft(Commons::<X>cast)
.unwrap(
Expand Down
Loading

0 comments on commit 6fdf740

Please sign in to comment.