Skip to content
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

Validate receiver object properties to shorten the code #71

Open
ydanneg opened this issue Dec 16, 2021 · 1 comment · May be fixed by #72
Open

Validate receiver object properties to shorten the code #71

ydanneg opened this issue Dec 16, 2021 · 1 comment · May be fixed by #72

Comments

@ydanneg
Copy link

ydanneg commented Dec 16, 2021

Problem

Currently we have to provide references to a class properties to validate like that

data class LongLongLongClassNameEmployee(val id: Int, val name: String, val email: String) {
    init {
        validate(this) {
            validate(LongLongLongClassNameEmployee::id).isPositive()
            validate(LongLongLongClassNameEmployee::name).hasSize(min = 3, max = 80)
            validate(LongLongLongClassNameEmployee::email).isNotBlank().isEmail()
        }
    }
}
  • It becomes very annoying when class names are long.
  • It is also confusing and questionable: why we have to provide type if we already work with an instance of this class provided through validate(this)?

The problem is that we can't currently provide property references like that:

data class LongLongLongClassNameEmployee(val id: Int, val name: String, val email: String) {
    init {
        validate(this) { employee ->
            validate(employee::id).isPositive()
            validate(employee::name).hasSize(min = 3, max = 80)
            validate(employee::email).isNotBlank().isEmail()
        }
    }
}

or even like this:

data class LongLongLongClassNameEmployee(val id: Int, val name: String, val email: String) {
    init {
        validate(this) {
            validate(it::id).isPositive()
            validate(it::name).hasSize(min = 3, max = 80)
            validate(it::email).isNotBlank().isEmail()
        }
    }
}

This is due to a limitation of Validator implementation that works only with KProperty1 property types of a Kotlin Reflect package.

When we reference class property Kotlin returns KProperty1 type which is now used in Validator implementation.
When we reference class instance property Kotlin returns KProperty0 type which is not supported by Validator implementation.

Possible solution

Validator could work with both KProperty0 and KProperty1 types (by overloading validate functions) that will give us the way to get property from a validation receiver directly

Suggested working test:

@Test
    fun `should validate by KProperty0`() {
        validate(Employee(company = Company(1))) {
            validate(it::company).isNotNull().validate { company ->
                validate(company::id).isNotNull()
            }
            validate(it::id).isNull()
            validate(it::address).isNull()
            validate(it::name).isNull()
        }
    }
ydanneg added a commit to ydanneg/valiktor that referenced this issue Dec 16, 2021
@ydanneg ydanneg linked a pull request Dec 16, 2021 that will close this issue
@PierrickPuimeanChieze
Copy link

I really want this, because it also help to build complexe validation, as bound properties allow to retrieve value of these said property

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants