Case
Declarative branching without switch fall-through.
Case lets you express conditional logic as data: each branch is a pair of condition and result, evaluated in order. Unlike switch, there is no fall-through; unlike if/else, every branch must yield a Result<T>.
API at a glance
Case exposes three static methods:
Case.matchCase(Supplier<Boolean> condition, Supplier<Result<T>> value)โ builds one branch.Case.matchCase(Supplier<Result<T>> value)โ builds the default branch (aDefaultCase<T>).Case.match(DefaultCase<T> defaultCase, Case<T>... matchers)โ evaluates the branches and returns the first matchingResult<T>. Falls back to the default if none match.
Basic usage
import static com.svenruppert.functional.matcher.Case.match;
import static com.svenruppert.functional.matcher.Case.matchCase;
import static com.svenruppert.functional.model.Result.success;
import static com.svenruppert.functional.model.Result.failure;
int score = 87;
Result<String> grade = match(
matchCase(() -> success("F")), // default
matchCase(() -> score >= 90, () -> success("A")),
matchCase(() -> score >= 80, () -> success("B")),
matchCase(() -> score >= 70, () -> success("C"))
);
grade.ifPresentOrElse(
System.out::println, // "B"
err -> System.err.println("no match: " + err)
);
Both the condition and the value are wrapped in Suppliers โ they are evaluated lazily, in the order they appear, and only until the first match.
Functions as results
Because each branch returns a Result<T>, T can be anything โ including a Function. That lets you assemble computation pipelines based on input:
Result<Function<Integer, Integer>> op = match(
matchCase(() -> success(v -> v)), // identity
matchCase(() -> x == 1, () -> success(v -> v + 1)),
matchCase(() -> x == 2, () -> success(v -> v + 2)),
matchCase(() -> x > 2, () -> success(v -> v + 3))
);
op.map(f -> f.apply(10))
.ifPresent(System.out::println);
When to reach for Case
Case vs switch vs if/else
Use
Case when branch order matters and each branch needs to produce a value declaratively. Stick with switch for cheap enum/int dispatch, and with if/else when you don’t need a result.