diff options
Diffstat (limited to 'src/main/java/org/pacien/lemonad/validation')
3 files changed, 249 insertions, 0 deletions
diff --git a/src/main/java/org/pacien/lemonad/validation/ValidationResult.java b/src/main/java/org/pacien/lemonad/validation/ValidationResult.java new file mode 100644 index 0000000..65bb389 --- /dev/null +++ b/src/main/java/org/pacien/lemonad/validation/ValidationResult.java | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * lemonad - Some functional sweetness for Java | ||
3 | * Copyright (C) 2019 Pacien TRAN-GIRARD | ||
4 | * | ||
5 | * This program is free software: you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Affero General Public License as | ||
7 | * published by the Free Software Foundation, either version 3 of the | ||
8 | * License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.lemonad.validation; | ||
20 | |||
21 | import org.pacien.lemonad.attempt.Attempt; | ||
22 | |||
23 | import java.util.Arrays; | ||
24 | import java.util.List; | ||
25 | import java.util.Objects; | ||
26 | import java.util.function.BiConsumer; | ||
27 | import java.util.function.Consumer; | ||
28 | import java.util.function.Function; | ||
29 | import java.util.stream.Stream; | ||
30 | |||
31 | import lombok.NonNull; | ||
32 | |||
33 | import static java.util.stream.Collectors.toUnmodifiableList; | ||
34 | import static org.pacien.lemonad.attempt.Attempt.failure; | ||
35 | import static org.pacien.lemonad.attempt.Attempt.success; | ||
36 | |||
37 | /** | ||
38 | * Wraps the result of the validation of a subject. | ||
39 | * | ||
40 | * @param <S> the subject type, | ||
41 | * @param <E> the error type. | ||
42 | * @author pacien | ||
43 | */ | ||
44 | public interface ValidationResult<S, E> { | ||
45 | /** | ||
46 | * @return whether no error have been reported during the validation. | ||
47 | */ | ||
48 | boolean isValid(); | ||
49 | |||
50 | /** | ||
51 | * @return whether some error have been reported during the validation. | ||
52 | */ | ||
53 | boolean isInvalid(); | ||
54 | |||
55 | /** | ||
56 | * @return the subject of the validation. | ||
57 | */ | ||
58 | S getSubject(); | ||
59 | |||
60 | /** | ||
61 | * @return the potentially empty list of reported validation errors. | ||
62 | */ | ||
63 | List<E> getErrors(); | ||
64 | |||
65 | /** | ||
66 | * @param consumer a subject consumer called if the validation is successful. | ||
67 | * @return the current object. | ||
68 | */ | ||
69 | default ValidationResult<S, E> ifValid(@NonNull Consumer<? super S> consumer) { | ||
70 | if (isValid()) consumer.accept(getSubject()); | ||
71 | return this; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * @param consumer the consumer called with the validation subject and reported errors if the validation is failed. | ||
76 | * @return the current object. | ||
77 | */ | ||
78 | default ValidationResult<S, E> ifInvalid(@NonNull BiConsumer<? super S, ? super List<? super E>> consumer) { | ||
79 | if (!isValid()) consumer.accept(getSubject(), getErrors()); | ||
80 | return this; | ||
81 | } | ||
82 | |||
83 | /** | ||
84 | * @return an {@link Attempt} with a state corresponding to the one of the validation. | ||
85 | */ | ||
86 | default Attempt<S, List<E>> toAttempt() { | ||
87 | return isValid() ? success(getSubject()) : failure(getErrors()); | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * @param mapper a function transforming a {@link ValidationResult}. | ||
92 | * @return the transformed {@link ValidationResult}. | ||
93 | */ | ||
94 | default <SS, EE> ValidationResult<SS, EE> flatMap(@NonNull Function<? super ValidationResult<? super S, ? super E>, ? extends ValidationResult<? extends SS, ? extends EE>> mapper) { | ||
95 | //noinspection unchecked | ||
96 | return (ValidationResult<SS, EE>) mapper.apply(this); | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * @param subject an overriding subject. | ||
101 | * @param validationResults a {@link Stream} of {@link ValidationResult}s to merge. | ||
102 | * @return the merged {@link ValidationResult} containing all errors from the supplied ones. | ||
103 | */ | ||
104 | static <S, E> ValidationResult<S, E> merge(S subject, @NonNull Stream<? extends ValidationResult<?, ? extends E>> validationResults) { | ||
105 | return new ValidationResultContainer<>( | ||
106 | subject, | ||
107 | validationResults.flatMap(res -> res.getErrors().stream()).collect(toUnmodifiableList())); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * @param subject the suject of the validation. | ||
112 | * @return a successful {@link ValidationResult}. | ||
113 | */ | ||
114 | static <S, E> ValidationResult<S, E> valid(S subject) { | ||
115 | return new ValidationResultContainer<>(subject, List.of()); | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * @param subject the suject of the validation. | ||
120 | * @param error a validation error. | ||
121 | * @param errors additional validation errors. | ||
122 | * @return a failed {@link ValidationResult} for the supplied subject. | ||
123 | */ | ||
124 | @SafeVarargs static <S, E> ValidationResult<S, E> invalid(S subject, E error, E... errors) { | ||
125 | return new ValidationResultContainer<>( | ||
126 | subject, | ||
127 | Stream.concat(Stream.of(error), Arrays.stream(errors)).map(Objects::requireNonNull).collect(toUnmodifiableList())); | ||
128 | } | ||
129 | } | ||
diff --git a/src/main/java/org/pacien/lemonad/validation/ValidationResultContainer.java b/src/main/java/org/pacien/lemonad/validation/ValidationResultContainer.java new file mode 100644 index 0000000..2c752f6 --- /dev/null +++ b/src/main/java/org/pacien/lemonad/validation/ValidationResultContainer.java | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * lemonad - Some functional sweetness for Java | ||
3 | * Copyright (C) 2019 Pacien TRAN-GIRARD | ||
4 | * | ||
5 | * This program is free software: you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Affero General Public License as | ||
7 | * published by the Free Software Foundation, either version 3 of the | ||
8 | * License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.lemonad.validation; | ||
20 | |||
21 | import java.util.List; | ||
22 | |||
23 | import lombok.NonNull; | ||
24 | import lombok.Value; | ||
25 | |||
26 | /** | ||
27 | * @author pacien | ||
28 | */ | ||
29 | @Value class ValidationResultContainer<S, E> implements ValidationResult<S, E> { | ||
30 | S subject; | ||
31 | @NonNull List<E> errors; | ||
32 | |||
33 | @Override public boolean isValid() { | ||
34 | return errors.isEmpty(); | ||
35 | } | ||
36 | |||
37 | @Override public boolean isInvalid() { | ||
38 | return !isValid(); | ||
39 | } | ||
40 | } | ||
diff --git a/src/main/java/org/pacien/lemonad/validation/Validator.java b/src/main/java/org/pacien/lemonad/validation/Validator.java new file mode 100644 index 0000000..a8a9e3f --- /dev/null +++ b/src/main/java/org/pacien/lemonad/validation/Validator.java | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * lemonad - Some functional sweetness for Java | ||
3 | * Copyright (C) 2019 Pacien TRAN-GIRARD | ||
4 | * | ||
5 | * This program is free software: you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU Affero General Public License as | ||
7 | * published by the Free Software Foundation, either version 3 of the | ||
8 | * License, or (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | package org.pacien.lemonad.validation; | ||
20 | |||
21 | import java.util.Arrays; | ||
22 | import java.util.List; | ||
23 | import java.util.Objects; | ||
24 | import java.util.function.Function; | ||
25 | import java.util.function.Predicate; | ||
26 | |||
27 | import lombok.NonNull; | ||