Skip to content

Commit 42ed52b

Browse files
Improve Validate APIs
1 parent 0f7a24f commit 42ed52b

File tree

10 files changed

+281
-287
lines changed

10 files changed

+281
-287
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66

77
### Changed
88

9+
- `Validator` to be an interface
10+
- `ValidatorScope` to `RulesScope`
11+
- `RulesScope` to be an interface
12+
913
### Deprecated
1014

1115
### Fixed
1216

1317
### Removed
1418

19+
- `name` parameter in `Validator`
20+
1521
### Updated
1622

1723
## [0.2.1] - 2025-01-10

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

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -482,44 +482,40 @@ public final class com/javiersc/kotlin/stdlib/tree/TreeNodeIterators : java/lang
482482
public static fun values ()[Lcom/javiersc/kotlin/stdlib/tree/TreeNodeIterators;
483483
}
484484

485-
public final class com/javiersc/kotlin/stdlib/validate/Validator {
486-
public fun <init> (Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/Unit;)V
487-
public final fun getBlock ()Lkotlin/jvm/functions/Function2;
488-
public final fun getName ()Ljava/lang/String;
489-
public final fun validate (Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
490-
}
491-
492-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope {
493-
public fun <init> ()V
494-
public fun <init> (Ljava/util/List;)V
495-
public synthetic fun <init> (Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
496-
public final fun getValidatables ()Ljava/util/List;
497-
public final fun invalid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
498-
public final fun invalidIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
499-
public final fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
500-
public final fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
501-
public final fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
502-
public final fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
503-
public final fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
504-
public final fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
505-
public final fun validator (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
506-
public final fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
507-
}
508-
509-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope$NestedScope {
510-
public fun <init> (Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
511-
}
512-
513-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable {
485+
public abstract interface class com/javiersc/kotlin/stdlib/validate/RulesScope {
486+
public abstract fun getRules ()Ljava/util/List;
487+
public abstract fun invalid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
488+
public abstract fun invalidIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
489+
public abstract fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
490+
public abstract fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
491+
public abstract fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
492+
public abstract fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
493+
public abstract fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
494+
public abstract fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
495+
public abstract fun validator (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
496+
public abstract fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
497+
}
498+
499+
public final class com/javiersc/kotlin/stdlib/validate/RulesScope$DefaultImpls {
500+
public static fun invalidIfIsBlank (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
501+
public static fun invalidIfIsEmpty (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
502+
public static fun invoke (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
503+
public static fun validatedBy (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
504+
public static fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
505+
}
506+
507+
public final class com/javiersc/kotlin/stdlib/validate/RulesScope$Rule {
514508
public fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
515-
public final fun component1 ()Lkotlin/jvm/functions/Function0;
516-
public final fun component2 ()Lkotlin/jvm/functions/Function0;
517-
public final fun copy (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;
518-
public static synthetic fun copy$default (Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;
519-
public fun equals (Ljava/lang/Object;)Z
520509
public final fun getOtherwise ()Lkotlin/jvm/functions/Function0;
521510
public final fun getPredicate ()Lkotlin/jvm/functions/Function0;
522-
public fun hashCode ()I
523-
public fun toString ()Ljava/lang/String;
511+
}
512+
513+
public abstract interface class com/javiersc/kotlin/stdlib/validate/Validator {
514+
public abstract fun getRuleScopeBlock ()Lkotlin/jvm/functions/Function2;
515+
public abstract fun validate (Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
516+
}
517+
518+
public final class com/javiersc/kotlin/stdlib/validate/Validator$DefaultImpls {
519+
public static fun validate (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
524520
}
525521

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

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -505,44 +505,40 @@ public final class com/javiersc/kotlin/stdlib/tree/TreeNodeIterators : java/lang
505505
public static fun values ()[Lcom/javiersc/kotlin/stdlib/tree/TreeNodeIterators;
506506
}
507507

508-
public final class com/javiersc/kotlin/stdlib/validate/Validator {
509-
public fun <init> (Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/Unit;)V
510-
public final fun getBlock ()Lkotlin/jvm/functions/Function2;
511-
public final fun getName ()Ljava/lang/String;
512-
public final fun validate (Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
513-
}
514-
515-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope {
516-
public fun <init> ()V
517-
public fun <init> (Ljava/util/List;)V
518-
public synthetic fun <init> (Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
519-
public final fun getValidatables ()Ljava/util/List;
520-
public final fun invalid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
521-
public final fun invalidIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
522-
public final fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
523-
public final fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
524-
public final fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
525-
public final fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
526-
public final fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
527-
public final fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
528-
public final fun validator (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
529-
public final fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
530-
}
531-
532-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope$NestedScope {
533-
public fun <init> (Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
534-
}
535-
536-
public final class com/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable {
508+
public abstract interface class com/javiersc/kotlin/stdlib/validate/RulesScope {
509+
public abstract fun getRules ()Ljava/util/List;
510+
public abstract fun invalid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
511+
public abstract fun invalidIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
512+
public abstract fun invalidIfIsBlank (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
513+
public abstract fun invalidIfIsEmpty (Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
514+
public abstract fun invoke (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
515+
public abstract fun valid (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
516+
public abstract fun validIf (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
517+
public abstract fun validatedBy (Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
518+
public abstract fun validator (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
519+
public abstract fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
520+
}
521+
522+
public final class com/javiersc/kotlin/stdlib/validate/RulesScope$DefaultImpls {
523+
public static fun invalidIfIsBlank (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
524+
public static fun invalidIfIsEmpty (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
525+
public static fun invoke (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
526+
public static fun validatedBy (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Ljava/lang/Object;Lcom/javiersc/kotlin/stdlib/validate/Validator;)V
527+
public static fun validatorFor (Lcom/javiersc/kotlin/stdlib/validate/RulesScope;Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)V
528+
}
529+
530+
public final class com/javiersc/kotlin/stdlib/validate/RulesScope$Rule {
537531
public fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
538-
public final fun component1 ()Lkotlin/jvm/functions/Function0;
539-
public final fun component2 ()Lkotlin/jvm/functions/Function0;
540-
public final fun copy (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;
541-
public static synthetic fun copy$default (Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/javiersc/kotlin/stdlib/validate/ValidatorScope$Validatable;
542-
public fun equals (Ljava/lang/Object;)Z
543532
public final fun getOtherwise ()Lkotlin/jvm/functions/Function0;
544533
public final fun getPredicate ()Lkotlin/jvm/functions/Function0;
545-
public fun hashCode ()I
546-
public fun toString ()Ljava/lang/String;
534+
}
535+
536+
public abstract interface class com/javiersc/kotlin/stdlib/validate/Validator {
537+
public abstract fun getRuleScopeBlock ()Lkotlin/jvm/functions/Function2;
538+
public abstract fun validate (Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
539+
}
540+
541+
public final class com/javiersc/kotlin/stdlib/validate/Validator$DefaultImpls {
542+
public static fun validate (Lcom/javiersc/kotlin/stdlib/validate/Validator;Ljava/lang/Object;)Lcom/javiersc/kotlin/stdlib/Either;
547543
}
548544

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.javiersc.kotlin.stdlib.validate
2+
3+
import com.javiersc.kotlin.stdlib.UseContextParameters
4+
import com.javiersc.kotlin.stdlib.validate.RulesScope.Rule
5+
6+
public interface RulesScope<E> {
7+
8+
public val rules: List<Rule<E>>
9+
10+
public fun invalid(predicate: () -> Boolean, otherwise: () -> E)
11+
12+
public fun invalidIf(predicate: () -> Boolean, otherwise: () -> E)
13+
14+
public operator fun <T> T.invoke(block: T.() -> Unit): T {
15+
block()
16+
return this
17+
}
18+
19+
public fun valid(predicate: () -> Boolean, otherwise: () -> E)
20+
21+
public fun validIf(predicate: () -> Boolean, otherwise: () -> E)
22+
23+
public fun <E2 : E, V2> validator(validator: Validator<E2, V2>, value: V2)
24+
25+
public infix fun <E2 : E, V2> Validator<E2, V2>.validatorFor(value: V2) {
26+
validator(this, value)
27+
}
28+
29+
public infix fun <E2 : E, V2> V2.validatedBy(validator: Validator<E2, V2>) {
30+
validator(validator, this)
31+
}
32+
33+
public class Rule<out E>(public val predicate: () -> Boolean, public val otherwise: () -> E)
34+
35+
@UseContextParameters
36+
public fun String.invalidIfIsEmpty(otherwise: () -> E) {
37+
invalidIf(predicate = ::isEmpty, otherwise = otherwise)
38+
}
39+
40+
@UseContextParameters
41+
public fun String.invalidIfIsBlank(otherwise: () -> E) {
42+
invalidIf(predicate = ::isBlank, otherwise = otherwise)
43+
}
44+
}
45+
46+
@Suppress("FunctionName")
47+
internal fun <E> RuleScope(): RulesScope<E> =
48+
object : RulesScope<E> {
49+
private val _rules: MutableList<Rule<E>> = mutableListOf()
50+
51+
override val rules: List<Rule<E>>
52+
get() = _rules.toList()
53+
54+
override fun invalidIf(predicate: () -> Boolean, otherwise: () -> E) {
55+
rule(predicate = { !predicate() }, otherwise = otherwise)
56+
}
57+
58+
override fun invalid(predicate: () -> Boolean, otherwise: () -> E) {
59+
rule(predicate = { !predicate() }, otherwise = otherwise)
60+
}
61+
62+
override fun validIf(predicate: () -> Boolean, otherwise: () -> E) {
63+
rule(predicate = predicate, otherwise = otherwise)
64+
}
65+
66+
override fun valid(predicate: () -> Boolean, otherwise: () -> E) {
67+
rule(predicate = predicate, otherwise = otherwise)
68+
}
69+
70+
override fun <E2 : E, V2> validator(validator: Validator<E2, V2>, value: V2) {
71+
val scope: RulesScope<E2> = RuleScope()
72+
validator.ruleScopeBlock(scope, value)
73+
_rules.addAll(scope.rules)
74+
}
75+
76+
private fun rule(predicate: () -> Boolean, otherwise: () -> E) {
77+
_rules.add(Rule(predicate = predicate, otherwise = otherwise))
78+
}
79+
}
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
11
package com.javiersc.kotlin.stdlib.validate
22

33
import com.javiersc.kotlin.stdlib.Either
4-
import com.javiersc.kotlin.stdlib.UseContextParameters
54
import com.javiersc.kotlin.stdlib.left
65
import com.javiersc.kotlin.stdlib.right
76

8-
public class Validator<E, V>
9-
@PublishedApi
10-
internal constructor(
11-
@PublishedApi internal val name: String,
12-
@PublishedApi internal val block: ValidatorScope<E, V>.(V) -> Unit,
13-
private val _unit0: Unit,
14-
) {
7+
public interface Validator<E, V> {
8+
9+
public val ruleScopeBlock: RulesScope<E>.(V) -> Unit
1510

1611
public fun <A : V> validate(value: A): Either<List<E>, A> {
17-
val validatorScope = ValidatorScope<E, V>()
18-
block(validatorScope, value)
12+
val ruleScope: RulesScope<E> = RuleScope<E>().also { it.ruleScopeBlock(value) }
1913

2014
val otherwises: List<E> =
21-
validatorScope.validatables.mapNotNull { if (it.predicate()) it.otherwise() else null }
22-
23-
if (otherwises.isEmpty()) return value.right()
15+
ruleScope.rules.mapNotNull { if (!it.predicate()) it.otherwise() else null }
2416

25-
val either: Either<List<E>, A> = otherwises.left()
26-
return either
17+
return if (otherwises.isEmpty()) value.right() else otherwises.left()
2718
}
2819
}
2920

3021
@Suppress("FunctionName")
31-
public inline fun <E : Any, reified T : Any> Validator(
32-
name: String = T::class.simpleName ?: "Validator",
33-
@UseContextParameters noinline block: ValidatorScope<E, T>.(T) -> Unit,
34-
): Lazy<Validator<E, T>> = lazy { Validator(name = name, block = block, _unit0 = Unit) }
22+
public inline fun <E : Any, reified V : Any> Validator(
23+
noinline block: RulesScope<E>.(V) -> Unit
24+
): Lazy<Validator<E, V>> = lazy {
25+
object : Validator<E, V> {
26+
27+
override val ruleScopeBlock: RulesScope<E>.(V) -> Unit = block
28+
}
29+
}
30+
31+
public inline fun <reified E : Any, reified T : Any> T.validateWith(
32+
validator: Validator<E, T>
33+
): Either<List<E>, T> {
34+
val validated: Either<List<E>, T> = validator.validate(this)
35+
return validated
36+
}

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

Lines changed: 0 additions & 65 deletions
This file was deleted.

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

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)