Last active
November 2, 2024 07:18
-
-
Save 987Nabil/1731324b1959e18a65e37016e6093526 to your computer and use it in GitHub Desktop.
This file contains hidden or 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.List; | |
record Book(NonBlankString title, ISBN isbn, NonEmptyList<Author> authors) { | |
static Either<String, Book> create(String title, String isbn, List<Author> authors) { | |
var nonBlankTitle = NonBlankString.create(title); | |
var nonEmptyAuthors = NonEmptyList.fromList(authors); | |
var isbn_ = ISBN.fromString(isbn); | |
if (nonBlankTitle.isRight() && nonEmptyAuthors.isRight() && isbn_.isRight()) { | |
return Either.right( | |
new Book( | |
nonBlankTitle.rightValue(), | |
isbn_.rightValue(), | |
nonEmptyAuthors.rightValue() | |
) | |
); | |
} else { | |
return (Either<String, Book>) Either.firstLeft(nonBlankTitle, isbn_, nonEmptyAuthors); | |
} | |
} | |
} |
This file contains hidden or 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
sealed interface Either<L, R> { | |
static <L, R> Either<L, R> left(L value) { | |
return new Left<>(value); | |
} | |
static <L, R> Either<L, R> right(R value) { | |
return new Right<>(value); | |
} | |
@SafeVarargs | |
static <L> Left<L, ?> firstLeft(Either<L, ?>... eithers) { | |
for (Either<L, ?> either : eithers) { | |
if (either instanceof Left<L, ?> left) { | |
return left; | |
} | |
} | |
throw new IllegalStateException("No left value present"); | |
} | |
public R rightValue(); | |
public default boolean isRight() { | |
return this instanceof Right; | |
} | |
record Left<L, R>(L value) implements Either<L, R> { | |
@Override | |
public R rightValue() { | |
throw new IllegalStateException("No right value present"); | |
} | |
} | |
record Right<L, R>(R value) implements Either<L, R> { | |
@Override | |
public R rightValue() { | |
return value; | |
} | |
} | |
} |
This file contains hidden or 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
// Impossible to use records, because they cant have private constructors | |
class ISBN { | |
private final String value; | |
private ISBN(String value) { | |
this.value = value; | |
} | |
static Either<String, ISBN> fromString(String value) { | |
if (value.length() != 13) { | |
return Either.left("ISBN must be 13 characters long"); | |
} | |
return Either.right(new ISBN(value)); | |
} | |
String value() { | |
return value; | |
} | |
} |
This file contains hidden or 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
// Impossible to use records, because they cant have private constructors | |
public class NonBlankString { | |
private final String value; | |
private NonBlankString(String value) { | |
this.value = value; | |
} | |
public String value() { | |
return value; | |
} | |
static Either<String, NonBlankString> create(String value) { | |
if (value.isBlank()) { | |
return Either.left("Value must not be blank"); | |
} | |
return Either.right(new NonBlankString(value)); | |
} | |
} |
This file contains hidden or 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 record NonEmptyList<T>(T head, List<T> tail) { | |
static <T> Either<String, NonEmptyList<T>> fromList(List<T> list) { | |
if (list.isEmpty()) { | |
return Either.left("NonEmptyList cannot be created from an empty list"); | |
} | |
return Either.right(new NonEmptyList<>(list.getFirst(), list.subList(1, list.size()))); | |
} | |
// Might need some accessors in real life | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment