Skip to content

Commit

Permalink
Merge pull request #143 from aNNiMON/exceptional-enhancements
Browse files Browse the repository at this point in the history
Exceptional enhancements
  • Loading branch information
aNNiMON committed Aug 14, 2017
2 parents de6545b + 1a8d3eb commit 3bfd8df
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 5 deletions.
44 changes: 39 additions & 5 deletions stream/src/main/java/com/annimon/stream/Exceptional.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static <T> Exceptional<T> of(ThrowableSupplier<T, Throwable> supplier) {
try {
return new Exceptional<T>(supplier.get(), null);
} catch (Throwable throwable) {
return new Exceptional<T>(null, throwable);
return of(throwable);
}
}

Expand Down Expand Up @@ -73,6 +73,15 @@ private Exceptional(T value, Throwable throwable) {
public T get() {
return value;
}

/**
* Checks value present (i.e. there were no exceptions).
*
* @return {@code true} if a value present, {@code false} otherwise
*/
public boolean isPresent() {
return throwable == null;
}

/**
* Returns inner value if there were no exceptions, otherwise returns {@code other}.
Expand All @@ -83,7 +92,18 @@ public T get() {
public T getOrElse(T other) {
return throwable == null ? value : other;
}


/**
* Returns inner value if there were no exceptions, otherwise returns value produced by supplier function.
*
* @param other the supplier function that produces value if there were any exception
* @return inner value if there were no exceptions, otherwise value produced by supplier function
* @since 1.1.9
*/
public T getOrElse(Supplier<? extends T> other) {
return throwable == null ? value : other.get();
}

/**
* Wraps inner value with {@code Optional} container
*
Expand Down Expand Up @@ -160,6 +180,20 @@ public Exceptional<T> or(Supplier<Exceptional<T>> supplier) {
return Objects.requireNonNull(supplier.get());
}

/**
* Applies custom operator on {@code Exceptional}.
*
* @param <R> the type of the result
* @param function a transforming function
* @return a result of the transforming function
* @throws NullPointerException if {@code function} is null
* @since 1.1.9
*/
public <R> R custom(Function<Exceptional<T>, R> function) {
Objects.requireNonNull(function);
return function.apply(this);
}

/**
* Invokes mapping function on inner value if there were no exceptions.
*
Expand All @@ -170,13 +204,13 @@ public Exceptional<T> or(Supplier<Exceptional<T>> supplier) {
*/
public <U> Exceptional<U> map(ThrowableFunction<? super T, ? extends U, Throwable> mapper) {
if (throwable != null) {
return new Exceptional<U>(null, throwable);
return of(throwable);
}
Objects.requireNonNull(mapper);
try {
return new Exceptional<U>(mapper.apply(value), null);
} catch (Throwable t) {
return new Exceptional<U>(null, t);
return of(t);
}
}

Expand Down Expand Up @@ -241,7 +275,7 @@ public Exceptional<T> recover(final ThrowableFunction<Throwable, ? extends T, Th
try {
return new Exceptional<T>(function.apply(throwable), null);
} catch (Throwable throwable) {
return new Exceptional<T>(null, throwable);
return of(throwable);
}
}

Expand Down
77 changes: 77 additions & 0 deletions stream/src/test/java/com/annimon/stream/ExceptionalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.annimon.stream.function.Supplier;
import com.annimon.stream.function.ThrowableFunction;
import com.annimon.stream.function.ThrowableSupplier;
import com.annimon.stream.function.UnaryOperator;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
Expand All @@ -27,6 +28,17 @@ public void testGet() {
assertEquals(10, value);
}

@Test
public void testIsPresent() {
assertTrue(Exceptional
.of(tenSupplier)
.isPresent());

assertFalse(Exceptional
.of(ioExceptionSupplier)
.isPresent());
}

@Test
public void testGetOrElse() {
int value = Exceptional
Expand All @@ -38,6 +50,22 @@ public void testGetOrElse() {
.of(tenSupplier)
.getOrElse(20);
assertEquals(10, value);

Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
return 3228;
}
};
value = Exceptional
.of(ioExceptionSupplier)
.getOrElse(supplier);
assertEquals(3228, value);

value = Exceptional
.of(tenSupplier)
.getOrElse(supplier);
assertEquals(10, value);
}

@Test
Expand Down Expand Up @@ -156,6 +184,55 @@ public Exceptional<Integer> get() {
.getOrThrow();
}

@Test
public void testCustomIntermediate() {
UnaryOperator<Exceptional<Integer>> incrementer = new UnaryOperator<Exceptional<Integer>>() {
@Override
public Exceptional<Integer> apply(Exceptional<Integer> exceptional) {
return exceptional
.map(new ThrowableFunction<Integer, Integer, Throwable>() {
@Override
public Integer apply(Integer integer) throws Throwable {
return integer + 1;
}
});
}
};
int value;
value = Exceptional.of(ioExceptionSupplier)
.custom(incrementer)
.getOrElse(0);
assertEquals(0, value);

value = Exceptional.of(tenSupplier)
.custom(incrementer)
.getOrElse(0);
assertEquals(11, value);
}

@Test
public void testCustomTerminal() {
Function<Exceptional<Integer>, Integer> incrementer = new Function<Exceptional<Integer>, Integer>() {
@Override
public Integer apply(Exceptional<Integer> exceptional) {
return exceptional.map(new ThrowableFunction<Integer, Integer, Throwable>() {
@Override
public Integer apply(Integer integer) throws Throwable {
return integer + 1;
}
}).getOrElse(0);
}
};
int value;
value = Exceptional.of(ioExceptionSupplier)
.custom(incrementer);
assertEquals(0, value);

value = Exceptional.of(tenSupplier)
.custom(incrementer);
assertEquals(11, value);
}

@Test
public void testMapWithoutException() {
String value = Exceptional
Expand Down

0 comments on commit 3bfd8df

Please sign in to comment.