[proposal] Introduce `ArgumentNValidator` combinators
See original GitHub issueThe current Validator<T>
requires an instance of type T
to use the validate
method.
This must allow for the existence of T
instance in an invalid state.
This Email example is a good example. It provides a factory method to prevent creation with invalid strings, but the constructor is exposed to allow users to instantiate it with invalid values.
However, modern general practice recommends that classes should not be instantiated with invalid values.
If the constructor of Email
is designed to throw a runtime exception when an invalid value is passed, it is not possible to define a Validator<Email>
.
So, how about making it possible to separate the type of the value received by the Validator
from the type of the result?
For example, the following.
public interface EssentialValidator<A, R> {
Validated<R> validate(A argument);
default <R2> EssentialValidator<A, R2> map(Function<? super R, ? extends R2> f) {
return a -> EssentialValidator.this.validate(a).map(f);
}
default <A2> EssentialValidator<A2, R> contramap(Function<? super A2, ? extends A> f) {
return a2 -> EssentialValidator.this.validate(f.apply(a2));
}
}
public final class ApplicativeValidator<T> implements EssentialValidator<T, T> {
...
With such an interface, it is possible to define EssentialValidator<String, Email>
as follows, even if Email is designed to throw an exception in its constructor.
EssentialValidator<String, Email> validator = ValidatorBuilder.<String>of()
.constraint(s -> s, "email", c -> c.notBlank().lessThanOrEqual(128).email())
.build()
.applicative()
.map(Email::new);
This approach is to define validators of a small type, and then combine them to create a large-structure validator. However, YAVI is originally designed to create a large-structure validator by extracting parts of a large-structure object and writing constraint after constraint. Therefore, I am not sure if this proposal is really necessary as a use case of YAVI or not.
Issue Analytics
- State:
- Created 2 years ago
- Comments:28 (28 by maintainers)
Top GitHub Comments
Work in progress. Looks pretty cool.
I’m sure you’re right, I think
split
will be fine there.