Created
March 11, 2016 12:03
-
-
Save poetix/d9ccc0d32fd4fb54722b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.function.*; | |
public final class Tunnel<E extends Exception> { | |
public static <E extends Exception, R> R call(Class<? extends E> exceptionClass, Function<Tunnel<E>, R> f) throws E { | |
try { | |
return f.apply(new Tunnel<>()); | |
} catch (TunnelledException e) { | |
throw exceptionClass.cast(e.getCause()); | |
} | |
} | |
public static <E extends Exception, R> void run(Class<? extends E> exceptionClass, Consumer<Tunnel<E>> c) throws E { | |
try { | |
c.accept(new Tunnel<>()); | |
} catch (TunnelledException e) { | |
throw exceptionClass.cast(e.getCause()); | |
} | |
} | |
public static final class TunnelledException extends RuntimeException { | |
public TunnelledException(Throwable cause) { | |
super(cause); | |
} | |
} | |
public interface TunnellingFunction<I, O, E extends Exception> extends Function<I, O> { | |
@Override | |
default O apply(I input) { | |
try { | |
return applyThrowing(input); | |
} catch (Exception e) { | |
throw new TunnelledException(e); | |
} | |
} | |
O applyThrowing(I input) throws E; | |
} | |
public interface TunnellingBiFunction<L, R, O, E extends Exception> extends BiFunction<L, R, O> { | |
@Override | |
default O apply(L left, R right) { | |
try { | |
return applyThrowing(left, right); | |
} catch (Exception e) { | |
throw new TunnelledException(e); | |
} | |
} | |
O applyThrowing(L left, R right) throws E; | |
} | |
public interface TunnellingSupplier<O, E extends Exception> extends Supplier<O> { | |
@Override | |
default O get() { | |
try { | |
return getThrowing(); | |
} catch (Exception e) { | |
throw new TunnelledException(e); | |
} | |
} | |
O getThrowing() throws E; | |
} | |
public interface TunnellingConsumer<I, E extends Exception> extends Consumer<I> { | |
@Override | |
default void accept(I input) { | |
try { | |
acceptThrowing(input); | |
} catch (Exception e) { | |
throw new TunnelledException(e); | |
} | |
} | |
void acceptThrowing(I input) throws E; | |
} | |
public interface TunnellingBiConsumer<L, R, E extends Exception> extends BiConsumer<L, R> { | |
@Override | |
default void accept(L left, R right) { | |
try { | |
acceptThrowing(left, right); | |
} catch (Exception e) { | |
throw new TunnelledException(e); | |
} | |
} | |
void acceptThrowing(L left, R right) throws E; | |
} | |
public <I, O> Function<I, O> wrap(TunnellingFunction<I, O, ? extends E> f) { | |
return f; | |
} | |
public <L, R, O> BiFunction<L, R, O> wrap(TunnellingBiFunction<L, R, O, ? extends E> f) { | |
return f; | |
} | |
public <O> Supplier<O> wrap(TunnellingSupplier<O, ? extends E> c) { | |
return c; | |
} | |
public <I> Consumer<I> wrap(TunnellingConsumer<I, ? extends E> c) { | |
return c; | |
} | |
public <L, R> BiConsumer<L, R> wrap(TunnellingBiConsumer<L, R, ? extends E> c) { | |
return c; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TunnelTest { | |
@Test | |
public void tunnelWrapsFunctions() throws IOException { | |
List<Integer> ints = Tunnel.call(IOException.class, tunnel -> | |
Stream.of(1, 2, 3).map(tunnel.wrap(i -> { | |
if (i == 0) { | |
throw new IOException(); | |
} | |
return i; | |
})).collect(Collectors.toList())); | |
} | |
@Test | |
public void tunnelWrapsCallables() throws IOException { | |
Tunnel.run(IOException.class, tunnel -> | |
Stream.of(1, 2, 3).forEach(tunnel.wrap(i -> { | |
try { | |
System.out.println(i); | |
} catch (Exception e) { | |
throw new IOException(e); | |
} | |
}))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment