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

Add function and lambda accessor syntax #65

Merged
merged 12 commits into from
Sep 10, 2024

Conversation

NikkyAI
Copy link
Contributor

@NikkyAI NikkyAI commented Jan 31, 2023

may be a partial duplicate of #63 but have this code anyhow.. maybe it helps even a little bit

this allows validations of java libraries without needing to write a val ThatClass.someValue = getSomeValue() extensions for each property

it also allows to use aliased custom accessors

a example out of our codebase using this to validate com.nimbusds.jwt.SignedJWT

fun ValidationBuilder<SignedJWT>.hasSubject(expectedSubject: String) {
    SignedJWT::getJWTClaimsSet required {
        JWTClaimsSet::getSubject required {
            addConstraint("subject must be '{0}'", expectedSubject) { subject ->
                subject == expectedSubject
            }
        }

    }
}

fun ValidationBuilder<SignedJWT>.hasClaimWithValue(claim: String, expected: String) {
    SignedJWT::getJWTClaimsSet required {
        val accessClaim = { it: JWTClaimsSet ->
            it.getStringClaim(claim) ?: null
        }
        accessClaim.required("getStringClaim($claim)") {
            addConstraint(
                "claim '{0}' must be '{1}'",
                claim,
                expected
            ) { value ->
                value == expected
            }
        }
    }
}

i added tests functionAccessorSyntax, lambdaAccessorSyntax, complexLambdaAccessors to demonstrate usage of this syntax

@nlochschmidt nlochschmidt changed the base branch from master to main March 29, 2024 11:47
@dhoepelman
Copy link
Collaborator

Looks interesting, I have definitely encountered this. On my list to review for inclusion

@dhoepelman
Copy link
Collaborator

dhoepelman commented May 10, 2024

If we wait long enough this will likely be solved by Kotlin itself, synthetic java accessors are scheduled for kotlin 2.1:
https://youtrack.jetbrains.com/issue/KT-8575/Support-Java-synthetic-property-references. It's currently available behind a language version feature flag, although I don't know the right incantation for 1.9 or 2.0.

Still, allowing constraints to be specified for any function/lambda seems a good feature to have in general, if only because I find it annoying to not be able to easily specify constraints on nested things. Supporting KFunction in addition to KProperty also makes a lot of sense.

Comment on lines 198 to 200
getPassword("getPasswordLambda") {
minLength(1)
}
Copy link
Collaborator

@dhoepelman dhoepelman May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about this as an API for lambdas

Suggested change
getPassword("getPasswordLambda") {
minLength(1)
}
get("password", { it.password }) {
minLength(1)
}

I think that should be possible with

/**
 * Transform the value into anything else and add a validation for it.
 * @param name The name that should be reported in validation errors
 * @param prop The function to get the value you want add a validation on
 * @see run
 */
abstract fun <R> get(name: String, prop: (T) -> R, init: ValidationBuilder<R>.() -> Unit)

@dhoepelman
Copy link
Collaborator

Fixes #14

@NikkyAI
Copy link
Contributor Author

NikkyAI commented May 23, 2024

yep, I think this works for us

@elijah-pl
Copy link

This issue you may find interesting 🙂
Having options for Kotlin pre-2.1 would be great though!
https://youtrack.jetbrains.com/issue/KT-8575/Support-Java-synthetic-property-references

@dhoepelman dhoepelman changed the title add function and lambda accessor syntax Add function and lambda accessor syntax Sep 10, 2024
@dhoepelman
Copy link
Collaborator

@NikkyAI @jillesvangurp Thanks a lot for the contribution! I've massaged the API into something I think can provide a good basis, see the new README. Intend to release this soon-ish as 0.7.0. Let me know if you have any feedback.

@dhoepelman dhoepelman added this to the v0.7.0 milestone Sep 10, 2024
@dhoepelman dhoepelman enabled auto-merge (squash) September 10, 2024 11:42
@dhoepelman dhoepelman enabled auto-merge (squash) September 10, 2024 12:12
@dhoepelman dhoepelman merged commit 2d9ba43 into konform-kt:main Sep 10, 2024
2 checks passed
@jillesvangurp
Copy link
Collaborator

Great!

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

Successfully merging this pull request may close these issues.

4 participants