Skip to content

Commit

Permalink
move static methods to Eithers, add toOptionalList
Browse files Browse the repository at this point in the history
  • Loading branch information
h908714124 committed Jul 22, 2021
1 parent 8838863 commit ee08d4a
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 74 deletions.
52 changes: 0 additions & 52 deletions src/main/java/io/jbock/util/Either.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.jbock.util;

import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collector;

/**
* A class that acts as a container for a value of one of two types. An Either
Expand Down Expand Up @@ -49,56 +47,6 @@ public static <L, R> Either<L, R> right(R value) {
return new Right<>(value);
}

/**
* Returns a collector that accumulates a Right containing all values in the original order,
* if there are no Left instances in the stream.
* If the stream contains a Left, it accumulates a Left containing the first LHS value in the stream.
*
* @param <L> the LHS type
* @param <R> the RHS type
* @return a Right containing all RHS values in the stream,
* or, if an LHS value exists, a Left containing the first such value
*/
public static <L, R> Collector<Either<? extends L, ? extends R>, ?, Either<L, List<R>>> toValidList() {
return new ValidatingCollector<>();
}

/**
* Returns a collector that accumulates a Right containing all values in the original order,
* if there are no Left instances in the stream.
* If the stream contains a Left, it accumulates a Left containing all LHS values in the stream,
* in the original order.
*
* @param <L> the LHS type
* @param <R> the RHS type
* @return a list of the RHS values in the stream,
* or, if an LHS value exists, a nonempty list of all LHS values
*/
public static <L, R> Collector<Either<? extends L, ? extends R>, ?, Either<List<L>, List<R>>> toValidListAll() {
return new ValidatingCollectorAll<>();
}

/**
* If the provided list is empty, returns an empty {@link Optional}.
* Otherwise, returns an {@code Optional} containing the list.
*
* <p>This utility method can sometimes be used to express a
* {@link #filter(Function)} operation more efficiently.
*
* @param values a list of objects
* @param <T> the type of the members of {@code values}
* @return an {@code Optional} which is empty if and only if {@code values}
* is empty
*/
public static <T> Optional<List<T>> optionalList(List<? extends T> values) {
if (values.isEmpty()) {
return Optional.empty();
}
@SuppressWarnings("unchecked")
List<T> result = (List<T>) values;
return Optional.of(result);
}

/**
* If this is a Right, returns a Right containing the result of applying
* the mapper function to the RHS value.
Expand Down
96 changes: 96 additions & 0 deletions src/main/java/io/jbock/util/Eithers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package io.jbock.util;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
* This class contains static utility methods related to
* the {@link Either} type.
*/
public final class Eithers {

private Eithers() {
}

/**
* Returns a {@code Collector} that accumulates the input elements into
* a Right containing all values in the original order,
* but only if there are no Left instances in the stream.
* If the stream does contain a Left instance, it discards the Right instances and
* accumulates a Left instance, which contains the first LHS value in the stream,
* in encounter order.
*
* @param <L> the type of the LHS values in the stream
* @param <R> the type of the RHS values in the stream
* @return a {@code Collector} which collects all the input elements into
* a Right containing all RHS values in the stream, or,
* if an LHS value exists, a Left containing the first LHS value
*/
public static <L, R> Collector<Either<? extends L, ? extends R>, ?, Either<L, List<R>>> toValidList() {
return new ValidatingCollector<>();
}

/**
* Returns a {@code Collector} that accumulates the input elements into
* a Right containing all values in the original order,
* but only if there are no Left instances in the stream.
* If the stream does contain a Left instance, it discards the Right instances and
* accumulates a Left containing only the LHS values,
* in encounter order.
*
* @param <L> the type of the LHS values in the stream
* @param <R> the type of the RHS values in the stream
* @return a {@code Collector} which collects all the input elements into
* a Right containing all RHS values in the stream,
* or, if an LHS value exists, a Left containing a nonempty list
* of all LHS values in the stream
*/
public static <L, R> Collector<Either<? extends L, ? extends R>, ?, Either<List<L>, List<R>>> toValidListAll() {
return new ValidatingCollectorAll<>();
}

/**
* Returns a {@code Collector} that accumulates the input elements into
* a new {@code List}. There are no guarantees on the type, mutability,
* serializability, or thread-safety of the {@code List} returned.
* The resulting list is wrapped in an {@code Optional},
* which is empty if and only if the list is empty.
*
* @see #optionalList(List)
* @param <T> the type of the input elements
* @return a list of the RHS values in the stream,
* or, if an LHS value exists, a nonempty list of all LHS values
*/
public static <T> Collector<T, ?, Optional<List<T>>> toOptionalList() {
return Collectors.collectingAndThen(
Collectors.toList(),
Eithers::optionalList);
}

/**
* If the provided list is empty, returns an empty {@link Optional}.
* Otherwise, returns an {@code Optional} containing the nonempty
* input list.
*
* <p>Note: The resulting {@code Optional} might be used in a
* {@link Either#filter(Function) filter} or
* {@link Either#filterLeft(Function) filterLeft} operation.
*
* @see #toOptionalList()
* @param values a list of objects
* @param <T> the type of the members of {@code values}
* @return an {@code Optional} which is either empty, or
* contains a nonempty list
*/
public static <T> Optional<List<T>> optionalList(List<? extends T> values) {
if (values.isEmpty()) {
return Optional.empty();
}
@SuppressWarnings("unchecked")
List<T> result = (List<T>) values;
return Optional.of(result);
}
}
2 changes: 1 addition & 1 deletion src/main/java/io/jbock/util/ValidatingCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.stream.Collector;

/**
* Internal implementation of {@link Either#toValidList()}.
* Internal implementation of {@link Eithers#toValidList()}.
*
* @param <L> the type of the LHS values in the stream
* @param <R> the type of the RHS values in the stream
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/jbock/util/ValidatingCollectorAll.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.stream.Collector;

/**
* Internal implementation of {@link Either#toValidListAll()}.
* Internal implementation of {@link Eithers#toValidListAll()}.
*
* @param <L> the type of the LHS values in the stream
* @param <R> the type of the RHS values in the stream
Expand Down
8 changes: 0 additions & 8 deletions src/test/java/io/jbock/util/EitherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

Expand Down Expand Up @@ -135,11 +134,4 @@ void testOrElseThrow() {
Either<String, String> right = Either.right("2");
assertEquals("2", right.orElseThrow(IllegalArgumentException::new));
}

@Test
void testOptionalList() {
assertEquals(Optional.empty(), Either.optionalList(List.of()));
assertEquals(Optional.of(List.of(1)), Either.optionalList(List.of(1)));
assertEquals(Optional.of(List.of("1", "2")), Either.optionalList(List.of("1", "2")));
}
}
37 changes: 37 additions & 0 deletions src/test/java/io/jbock/util/EithersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.jbock.util;

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import static io.jbock.util.Eithers.optionalList;
import static io.jbock.util.Eithers.toOptionalList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class EithersTest {

@Test
void testOptionalList() {
assertEquals(Optional.empty(), optionalList(List.of()));
assertEquals(Optional.of(List.of(1)), optionalList(List.of(1)));
}

@Test
void testToValidList() {
assertTrue(Eithers.toValidList() instanceof ValidatingCollector);
}

@Test
void testToValidListAll() {
assertTrue(Eithers.toValidListAll() instanceof ValidatingCollectorAll);
}

@Test
void testToOptionalList() {
assertEquals(Optional.empty(), Stream.of().collect(toOptionalList()));
assertEquals(Optional.of(List.of(1)), Stream.of(1).collect(toOptionalList()));
}
}
6 changes: 0 additions & 6 deletions src/test/java/io/jbock/util/ValidatingCollectorAllTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import static io.jbock.util.Either.left;
import static io.jbock.util.Either.right;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ValidatingCollectorAllTest {

Expand All @@ -32,11 +31,6 @@ void testRight() {
assertEquals(right(List.of(1, 2, 3)), apply(List.of(right(1), right(2), right(3))));
}

@Test
void testFactoryMethod() {
assertTrue(Either.toValidList() instanceof ValidatingCollector);
}

private Either<List<String>, List<Integer>> apply(List<Either<String, Integer>> data) {
return data.stream().collect(new ValidatingCollectorAll<>());
}
Expand Down
6 changes: 0 additions & 6 deletions src/test/java/io/jbock/util/ValidatingCollectorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import static io.jbock.util.Either.left;
import static io.jbock.util.Either.right;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ValidatingCollectorTest {

Expand All @@ -32,11 +31,6 @@ void testRight() {
assertEquals(right(List.of(1, 2, 3)), apply(List.of(right(1), right(2), right(3))));
}

@Test
void testFactoryMethod() {
assertTrue(Either.toValidListAll() instanceof ValidatingCollectorAll);
}

private Either<String, List<Integer>> apply(List<Either<String, Integer>> data) {
return data.stream().collect(new ValidatingCollector<>());
}
Expand Down

0 comments on commit ee08d4a

Please sign in to comment.