-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data validation #2
Comments
I don't see any variants for wrapping concretely @ImmutableImpl
interface Foo {
val value: String
@Validator(propertyName = "value")
val validator: Validator<String> get() = StringLengthValidator(1..99)
} Minuses I see:
Also, with same idea we can make companion object with next view: @ImmutableImpl
interface Foo {
val value: String
@ValidatorsStorage
private companion object Validation {
val value: Validatable<String> = Validatable(property = Foo::value, validator = StringLengthValidator(0..99))
}
} |
finally, I propose next variant: /**
* Validator contract:
* - Validator always should be object.
*/
interface Validator<T> {
/**
* Checks [value] for correctness.
* If return value is `false` — implier will throw an exception.
*/
fun validate(value: T): Boolean
}
annotation class Validates<T>(val validator: KClass<Validator<T>>)
object DigitStringValidator : Validator<String> {
override fun validate(value: String): Boolean {
return value.all { it.isDigit() }
}
}
@ImmutableImpl
interface Entity {
@Validates(DigitStringValidator::class)
val value: String
} Minuse I see is impossibility to provide some additional parameters to validator. But I think it can be avoided in next way: abstract class IntValueValidator(val min: Int, val max: Int) : Validator<Int> {
override fun validate(value: Int): Boolean {
return value >= min && value =< max
}
companion object Month : IntValueValidator(1, 12)
companion object Hour24 : IntValueValidator(0, 23)
// etc
} However it still not a case for some situations, but I don't see any other possible solutions. |
Also, we can provide annotation that will provide safe way to institiate an object: @Immutable
@SafeFactoryImpl
interface Entity {
@Validates(EmailValidator::class)
val email: String
@Validates(StringLengthValidator.FirstName::class)
val firstName: String
}
// generates
sealed interface EntityCreationResult {
object EmailIsInvalid : EntityCreationResult
object FirstNameIsInvalid : EntityCreationResult
class Success(val value: Entity) : EntityCreationResult
}
fun Entity(email: String, firstName: String): EntityCreationResult {
if(!EmailValidator.validate(email))
return EntityCreationResult.EmailIsInvalid
if(!StringLengthValidator.FirstName.validate(firstName))
return EntityLengthValidator.FirstNameIsInvalid
return EmailCreationResult.Success(ImmutableEntity(email, firstName))
} |
The most complex thing here is how to design validators.
I see three ways:
Originally posted by @y9san9 in #1 (comment)
The text was updated successfully, but these errors were encountered: