Interface Guard<T>
- Type Parameters:
T- the type of value being validated
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
Validated result when applied to a value.
Guard<T> is a functional interface whose single abstract method is
check(T), which returns
Validated<NonEmptyList<String>, T>: Valid(value) when the predicate passes,
or Invalid(errors) when it fails.
Guards are designed to be defined once and reused across validation pipelines, eliminating
the repetitive if/Validated.invalidNel(Object) pattern:
Guard<String> notBlank = Guard.of(s -> !s.isBlank(), "must not be blank");
Guard<String> minLength3 = Guard.of(s -> s.length() >= 3, "must be at least 3 chars");
Guard<String> alphanumeric = Guard.of(s -> s.matches("[\\w]+"), "must be alphanumeric");
Guard<String> username = notBlank.and(minLength3).and(alphanumeric);
username.check("al"); // Invalid(["must be at least 3 chars"])
username.check("ok?"); // Invalid(["must be alphanumeric"])
username.check("alice"); // Valid("alice")
Composition semantics
and— both guards must pass; errors from all failing guards are accumulated (not fail-fast).or— the first passing guard short-circuits; if all fail, all errors are accumulated.negate/negate(message)— inverts the predicate.
-
Method Summary
Modifier and TypeMethodDescriptionReturns a composed guard that requires both this guard andotherto pass.Applies this guard tovalue.checkToOption(T value) Applies this guard tovalueand returns anOption<T>.default Result<T, NonEmptyList<String>> checkToResult(T value) Applies this guard tovalueand returns aResult<T, NonEmptyList<String>>.checkToResult(T value, Function<NonEmptyList<String>, E> toError) Applies this guard tovalueand returns aResult<T, E>, mapping the accumulated error list to a domain-specific error type viatoError.default <U> Guard<U> Returns aGuard<U>that appliesmapperto its input before checking.negate()Returns a guard that is the logical negation of this guard, using a generic error message.Returns a guard that is the logical negation of this guard, using the supplied error message when the original guard passes.static <T> Guard<T> Creates aGuard<T>from a predicate and a static error message.static <T> Guard<T> Creates aGuard<T>from a predicate and a dynamic error message function.Returns a composed guard that passes when at least one of this guard orotherpasses.
-
Method Details
-
check
Applies this guard tovalue.- Parameters:
value- the value to validate; must not benull- Returns:
Valid(value)if the predicate passes, orInvalid(errors)if it fails
-
of
Creates aGuard<T>from a predicate and a static error message.Example:
Guard<String> notBlank = Guard.of(s -> !s.isBlank(), "must not be blank");- Type Parameters:
T- the value type- Parameters:
predicate- the condition that must hold for the value to be validerrorMessage- the error message produced when the predicate fails- Returns:
- a new
Guard<T> - Throws:
NullPointerException- ifpredicateorerrorMessageisnull
-
of
Creates aGuard<T>from a predicate and a dynamic error message function.The
errorMessageFnreceives the failing value so it can produce a context-specific message.Example:
Guard<Integer> max = Guard.of( n -> n <= 100, n -> "must be ≤ 100, got " + n );- Type Parameters:
T- the value type- Parameters:
predicate- the condition that must hold for the value to be validerrorMessageFn- function that produces an error message from the failing value- Returns:
- a new
Guard<T> - Throws:
NullPointerException- ifpredicateorerrorMessageFnisnull
-
and
Returns a composed guard that requires both this guard andotherto pass.Both guards are always evaluated — this is not fail-fast. Errors from all failing guards are accumulated into a single
NonEmptyList, so the caller receives a complete picture of all violations at once.Example:
Guard<Integer> positive = Guard.of(n -> n > 0, "must be positive"); Guard<Integer> even = Guard.of(n -> n % 2 == 0, "must be even"); Guard<Integer> positiveEven = positive.and(even); positiveEven.check(4); // Valid(4) positiveEven.check(3); // Invalid(["must be even"]) positiveEven.check(-1); // Invalid(["must be positive", "must be even"]) // — both guards evaluated, both errors collected- Parameters:
other- the guard that must also pass; must not benull- Returns:
- a composed
Guard<T> - Throws:
NullPointerException- ifotherisnull
-
or
Returns a composed guard that passes when at least one of this guard orotherpasses.Evaluation is short-circuit: if this guard passes,
otheris never evaluated. If both fail, errors from both guards are accumulated.Example:
Guard<String> email = Guard.of(s -> s.contains("@"), "must contain @"); Guard<String> phone = Guard.of(s -> s.matches("\\d+"), "must be digits"); Guard<String> contact = email.or(phone); contact.check("alice@example.com"); // Valid — email passes, phone not evaluated contact.check("12345"); // Valid — phone passes contact.check("hello"); // Invalid(["must contain @", "must be digits"])- Parameters:
other- the alternative guard; must not benull- Returns:
- a composed
Guard<T> - Throws:
NullPointerException- ifotherisnull
-
negate
Returns a guard that is the logical negation of this guard, using a generic error message.The composed guard returns
Valid(value)when this guard fails, andInvalid(["must not satisfy the condition"])when this guard passes. Usenegate(message)to supply a domain-specific error message.- Returns:
- the negated
Guard<T>
-
negate
Returns a guard that is the logical negation of this guard, using the supplied error message when the original guard passes.Example:
Guard<String> notAdmin = Guard.of(s -> s.equals("admin"), "is admin") .negate("username must not be 'admin'"); notAdmin.check("alice"); // Valid("alice") notAdmin.check("admin"); // Invalid(["username must not be 'admin'"])- Parameters:
errorMessage- the error message returned when the original guard passes- Returns:
- the negated
Guard<T> - Throws:
NullPointerException- iferrorMessageisnull
-
asPredicate
Returns a standardPredicate<T>that returnstruewhen this guard passes andfalsewhen it fails.Use this to integrate guards with standard Java APIs that accept
Predicate(e.g.,Stream.filter,Collection.removeIf).Example:
Guard<String> notBlank = Guard.of(s -> !s.isBlank(), "must not be blank"); List<String> valid = Stream.of("alice", " ", "bob", "") .filter(notBlank.asPredicate()) .toList(); // ["alice", "bob"]- Returns:
- a
Predicate<T>backed by this guard
-
contramap
Returns aGuard<U>that appliesmapperto its input before checking.This is the contravariant map operation: it adapts a guard written for type
Tto work on an enclosing typeUby projectingU → Tfirst. It is the idiomatic way to reuse field-level guards on whole objects.Example:
Guard<String> notBlank = Guard.of(s -> !s.isBlank(), "username must not be blank"); // Lift notBlank to validate User objects by their username field Guard<User> userGuard = notBlank.contramap(User::username); userGuard.check(new User("alice")); // Valid(user) userGuard.check(new User(" ")); // Invalid(["username must not be blank"])- Type Parameters:
U- the input type of the returned guard- Parameters:
mapper- function that extracts theTvalue from aU; must not benull- Returns:
- a new
Guard<U>that projectsU → Tbefore checking - Throws:
NullPointerException- ifmapperisnull
-
checkToResult
Applies this guard tovalueand returns aResult<T, NonEmptyList<String>>.Equivalent to
this.check(value).toResult()but removes the need to import and chain the conversion manually.- Parameters:
value- the value to validate- Returns:
Result.ok(value)if the guard passes, orResult.err(errors)if it fails
-
checkToResult
Applies this guard tovalueand returns aResult<T, E>, mapping the accumulated error list to a domain-specific error type viatoError.Use this at domain service boundaries where
Resultis the preferred container and the error type is richer than a plain list of strings.Example:
Guard<String> username = notBlank.and(minLength3); Result<String, ValidationException> result = username.checkToResult( input, errors -> new ValidationException("username", errors.toList()) );- Type Parameters:
E- the domain error type- Parameters:
value- the value to validatetoError- function mapping the accumulated error list toE- Returns:
Result.ok(value)on success, orResult.err(toError(errors))on failure- Throws:
NullPointerException- iftoErrorisnull
-
checkToOption
Applies this guard tovalueand returns anOption<T>.Returns
Some(value)when the guard passes andNonewhen it fails, discarding the error details. Use this when you only need to know whether a value is valid, not why it is not.Example:
Guard<String> notBlank = Guard.of(s -> !s.isBlank(), "must not be blank"); // Filter a stream keeping only valid values List<String> valid = Stream.of("alice", " ", "bob") .flatMap(s -> notBlank.checkToOption(s).stream()) .toList(); // ["alice", "bob"]- Parameters:
value- the value to validate- Returns:
Option.some(value)if the guard passes, orOption.none()if it fails
-