From d22db64e67d16b3e019eaa7085874215b0460375 Mon Sep 17 00:00:00 2001 From: Johann Pardanaud Date: Wed, 3 Jan 2024 14:00:13 +0100 Subject: [PATCH] core: implement scope control for the DSL (closes #25) --- CHANGELOG.md | 4 ++ documentation/topics/migration-guide.md | 56 +++++++++++++++++++ .../nesk/akkurate/validatables/Validatable.kt | 4 ++ 3 files changed, 64 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62d5ace8..0b8d5e85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### ⚠️ Breaking changes + +- [Scope control](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker) has been implemented for Akkurate's DSL ([#25](https://github.com/nesk/akkurate/issues/25)) + ### Fixed - Accessors for mutable properties are no longer improperly cast. ([#22](https://github.com/nesk/akkurate/issues/22)) diff --git a/documentation/topics/migration-guide.md b/documentation/topics/migration-guide.md index b3c34fab..25f31cf3 100644 --- a/documentation/topics/migration-guide.md +++ b/documentation/topics/migration-guide.md @@ -3,6 +3,62 @@ Some breaking changes might happen sometimes, especially until %product% reaches its first stable version. Here you can find how to migrate to a new version containing breaking changes. +## Version #unreleased# + +Akkurate improved its DSL by +implementing [scope control,](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker) which means +you can no longer implicitly reference a declaration of an outer receiver: + + + + +```kotlin +@Validate +data class Book(val title: String, val labels: List) + +val validateBook = Validator { + title.isNotBlank() + + labels { + each { + isNotBlank() + + hasSizeLowerThan(10) + // ❌ Compiler error: 'hasSizeLowerThan' can't be called + // in this context by implicit receiver. Use the explicit + // one if necessary. + // 💬 It happens because 'hasSizeLowerThan' is implicitly + // applied to the 'labels' property. + } + } +} +``` + + + + +```kotlin +@Validate +data class Book(val title: String, val labels: List) + +val validateBook = Validator { + title.isNotBlank() + + labels { + hasSizeLowerThan(10) + // ✅ Success: 'hasSizeLowerThan' is explicitly applied to the + // 'labels' property. + + each { + isNotBlank() + } + } +} +``` + + + + ## Version 0.4.0 The `Configuration` diff --git a/library/src/jvmMain/kotlin/dev/nesk/akkurate/validatables/Validatable.kt b/library/src/jvmMain/kotlin/dev/nesk/akkurate/validatables/Validatable.kt index b98382f7..9efb03af 100644 --- a/library/src/jvmMain/kotlin/dev/nesk/akkurate/validatables/Validatable.kt +++ b/library/src/jvmMain/kotlin/dev/nesk/akkurate/validatables/Validatable.kt @@ -27,6 +27,10 @@ import dev.nesk.akkurate.validateWith import kotlin.reflect.KFunction1 import kotlin.reflect.KProperty1 +@DslMarker +private annotation class ValidatableDslMarker + +@ValidatableDslMarker public class Validatable private constructor( private val wrappedValue: T, pathSegment: String?,