Skip to content

Commit 1211b99

Browse files
Add rulesFor to RulesScope
1 parent 42ed52b commit 1211b99

File tree

5 files changed

+102
-4
lines changed

5 files changed

+102
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Added
66

7+
- `rulesFor` to `RulesScope`
8+
79
### Changed
810

911
- `Validator` to be an interface

kotlin-stdlib/api/android/kotlin-stdlib.api

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,9 @@ public abstract interface class com/javiersc/kotlin/stdlib/validate/RulesScope {
489489
public abstract fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
490490
public abstract fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
491491
public abstract fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
492+
public abstract fun rule (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
493+
public abstract fun rulesFor ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
494+
public abstract fun rulesFor ([Lkotlin/reflect/KProperty0;Lkotlin/jvm/functions/Function2;)V
492495
public abstract fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
493496
public abstract fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
494497
public abstract fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
@@ -500,6 +503,8 @@ public final class com/javiersc/kotlin/stdlib/validate/RulesScope$DefaultImpls {
500503
public static fun invalidIfIsBlank (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
501504
public static fun invalidIfIsEmpty (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
502505
public static fun invoke (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
506+
public static fun rulesFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
507+
public static fun rulesFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;[Lkotlin/reflect/KProperty0;Lkotlin/jvm/functions/Function2;)V
503508
public static fun validatedBy (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
504509
public static fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
505510
}

kotlin-stdlib/api/jvm/kotlin-stdlib.api

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,9 @@ public abstract interface class com/javiersc/kotlin/stdlib/validate/RulesScope {
512512
public abstract fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
513513
public abstract fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
514514
public abstract fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
515+
public abstract fun rule (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
516+
public abstract fun rulesFor ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
517+
public abstract fun rulesFor ([Lkotlin/reflect/KProperty0;Lkotlin/jvm/functions/Function2;)V
515518
public abstract fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
516519
public abstract fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
517520
public abstract fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
@@ -523,6 +526,8 @@ public final class com/javiersc/kotlin/stdlib/validate/RulesScope$DefaultImpls {
523526
public static fun invalidIfIsBlank (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
524527
public static fun invalidIfIsEmpty (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
525528
public static fun invoke (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
529+
public static fun rulesFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
530+
public static fun rulesFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;[Lkotlin/reflect/KProperty0;Lkotlin/jvm/functions/Function2;)V
526531
public static fun validatedBy (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
527532
public static fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
528533
}

kotlin-stdlib/common/main/kotlin/com/javiersc/kotlin/stdlib/validate/RulesScope.kt

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,29 @@ package com.javiersc.kotlin.stdlib.validate
22

33
import com.javiersc.kotlin.stdlib.UseContextParameters
44
import com.javiersc.kotlin.stdlib.validate.RulesScope.Rule
5+
import kotlin.reflect.KProperty0
56

67
public interface RulesScope<E> {
78

89
public val rules: List<Rule<E>>
910

11+
public fun rule(predicate: () -> Boolean, otherwise: () -> E)
12+
13+
public fun <V> rulesFor(vararg values: V, block: (value: V) -> Unit) {
14+
for (value: V in values) {
15+
block(value)
16+
}
17+
}
18+
19+
public fun <V> rulesFor(
20+
vararg properties: KProperty0<V>,
21+
block: (property: String, value: V) -> Unit,
22+
) {
23+
for (property: KProperty0<V> in properties) {
24+
block(property.name, property.get())
25+
}
26+
}
27+
1028
public fun invalid(predicate: () -> Boolean, otherwise: () -> E)
1129

1230
public fun invalidIf(predicate: () -> Boolean, otherwise: () -> E)
@@ -51,6 +69,10 @@ internal fun <E> RuleScope(): RulesScope<E> =
5169
override val rules: List<Rule<E>>
5270
get() = _rules.toList()
5371

72+
override fun rule(predicate: () -> Boolean, otherwise: () -> E) {
73+
_rules.add(Rule(predicate = predicate, otherwise = otherwise))
74+
}
75+
5476
override fun invalidIf(predicate: () -> Boolean, otherwise: () -> E) {
5577
rule(predicate = { !predicate() }, otherwise = otherwise)
5678
}
@@ -72,8 +94,4 @@ internal fun <E> RuleScope(): RulesScope<E> =
7294
validator.ruleScopeBlock(scope, value)
7395
_rules.addAll(scope.rules)
7496
}
75-
76-
private fun rule(predicate: () -> Boolean, otherwise: () -> E) {
77-
_rules.add(Rule(predicate = predicate, otherwise = otherwise))
78-
}
7997
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.javiersc.kotlin.stdlib.validate
2+
3+
import com.javiersc.kotlin.stdlib._fixtures.Book
4+
import com.javiersc.kotlin.stdlib._fixtures.HarryPotterBook
5+
import com.javiersc.kotlin.stdlib._utils.assertLeft
6+
import com.javiersc.kotlin.stdlib._utils.assertRight
7+
import kotlin.test.Test
8+
9+
class ValidatorRulesForTest {
10+
11+
@Test
12+
fun given__a_validator_using_rulesFor_api_and_a_book__when__validates__then__is_valid() {
13+
val validator: Validator<String, Book> by Validator { book ->
14+
rulesFor(book::title, book.author::name) { property, value ->
15+
invalidIf(
16+
predicate = { value.any(Char::isDigit) },
17+
otherwise = { "The $property must not contain numbers" },
18+
)
19+
}
20+
}
21+
val validator2: Validator<String, Book> by Validator { book ->
22+
rulesFor(book.title, book.author.name) { value ->
23+
invalidIf(
24+
predicate = { value.any(Char::isDigit) },
25+
otherwise = { "The property must not contain numbers" },
26+
)
27+
}
28+
}
29+
HarryPotterBook.validateWith(validator).assertRight()
30+
HarryPotterBook.validateWith(validator2).assertRight()
31+
}
32+
33+
@Test
34+
fun given__a_validator_using_rulesFor_api_and_a_book__when__validates__then__is_invalid() {
35+
val validator: Validator<String, Book> by Validator { book ->
36+
rulesFor(book::title, book.author::name) { property, value ->
37+
invalidIf(
38+
predicate = { value.any(Char::isDigit) },
39+
otherwise = { "The $property must not contain numbers" },
40+
)
41+
}
42+
}
43+
val validator2: Validator<String, Book> by Validator { book ->
44+
rulesFor(book.title, book.author.name) { value ->
45+
invalidIf(
46+
predicate = { value.any(Char::isDigit) },
47+
otherwise = { "The property must not contain numbers" },
48+
)
49+
}
50+
}
51+
52+
val harryPotterBook1: Book =
53+
HarryPotterBook.copy(
54+
title = "${HarryPotterBook.title} 1",
55+
author = HarryPotterBook.author.copy(name = "${HarryPotterBook.author} 1"),
56+
)
57+
58+
harryPotterBook1
59+
.validateWith(validator)
60+
.assertLeft("The title must not contain numbers", "The name must not contain numbers")
61+
harryPotterBook1
62+
.validateWith(validator2)
63+
.assertLeft(
64+
"The property must not contain numbers",
65+
"The property must not contain numbers",
66+
)
67+
}
68+
}

0 commit comments

Comments
 (0)