Skip to content

Commit eb80024

Browse files
committed
✨ feat(config): add new validation annotations for configuration values
- introduce Contains, Directory, DisallowValues, EndsWith, ExistingFile, MaxDuration, MaxLength, MaxSize, MinDuration, MinSize, Namespace, NegativeNumber, NoDuplicates, NotEmpty, StartsWith, and WritablePath annotations - each annotation provides specific validation logic for configuration fields
1 parent 637d9cf commit eb80024

17 files changed

Lines changed: 178 additions & 0 deletions

File tree

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Contains.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Requires a string config value to contain a specific substring.
9+
*
10+
* This annotation ensures that the annotated string contains the specified substring.
11+
* If the validation fails, a `SerializationException` is thrown with a descriptive error message.
12+
*
13+
* @property value The substring that must be present in the string value.
14+
*/
715
@Target(AnnotationTarget.FIELD)
816
@Retention(AnnotationRetention.RUNTIME)
917
annotation class Contains(val value: String) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/Directory.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ import java.lang.reflect.Type
66
import kotlin.io.path.exists
77
import kotlin.io.path.isDirectory
88

9+
/**
10+
* Ensures that a configuration value represents a valid, existing directory.
11+
*
12+
* This annotation validates that the annotated value points to a directory that exists on the filesystem.
13+
* If the value does not exist, or if it does not represent a directory, validation will fail with a
14+
* `SerializationException`.
15+
*
16+
* This constraint supports different types of input, such as `Path`, `File`, and `String`, converting
17+
* them to a `Path` internally using the helper method `asPathOrNull`.
18+
*
19+
* Constraints:
20+
* - The value must point to an existing directory.
21+
* - The value must be convertible to a `Path` object.
22+
*
23+
* Intended for use on fields in configuration classes.
24+
*
25+
* Validation failure will throw a `SerializationException` with a descriptive message indicating the
26+
* problem with the directory path.
27+
*
28+
* Associated factory implementation provides the actual validation logic.
29+
*/
930
@Target(AnnotationTarget.FIELD)
1031
@Retention(AnnotationRetention.RUNTIME)
1132
annotation class Directory {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/DisallowValues.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Prevents specific values from being assigned to the annotated field.
9+
*
10+
* This annotation is used to define a set of disallowed string values for a field. If the annotated field's
11+
* value matches any of the specified disallowed values (case-insensitive), a `SerializationException` is thrown.
12+
*
13+
* @property values The array of string values that are disallowed.
14+
*/
715
@Target(AnnotationTarget.FIELD)
816
@Retention(AnnotationRetention.RUNTIME)
917
annotation class DisallowValues(vararg val values: String) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/EndsWith.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Validates that a string config value ends with a specified suffix.
9+
*
10+
* This annotation ensures that the annotated string ends with the provided suffix.
11+
* If the validation fails, a `SerializationException` is thrown with a descriptive error message.
12+
*
13+
* @property suffix The suffix that the string value must end with.
14+
*/
715
@Target(AnnotationTarget.FIELD)
816
@Retention(AnnotationRetention.RUNTIME)
917
annotation class EndsWith(val suffix: String) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/ExistingFile.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ import java.nio.file.Path
88
import kotlin.io.path.exists
99
import kotlin.io.path.isRegularFile
1010

11+
/**
12+
* Requires that the annotated field refers to an existing file.
13+
*
14+
* This annotation ensures that the value of the annotated field corresponds to
15+
* a valid file path that exists and is a regular file. If the validation fails,
16+
* a `SerializationException` is thrown with a descriptive error message.
17+
*
18+
* The value can be:
19+
* - A `Path` object.
20+
* - A `File` object.
21+
* - A `String` representing the file path.
22+
*
23+
* If the value is not convertible to a file path or the file does not exist
24+
* or is not a regular file, the validation fails.
25+
*
26+
* This annotation is typically used for configuration values to ensure
27+
* that specified file paths are valid at runtime.
28+
*/
1129
@Target(AnnotationTarget.FIELD)
1230
@Retention(AnnotationRetention.RUNTIME)
1331
annotation class ExistingFile {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxDuration.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
55
import org.spongepowered.configurate.serialize.SerializationException
66
import java.lang.reflect.Type
77

8+
/**
9+
* Annotation for constraining a `ConfigDuration`'s value to a maximum duration.
10+
*
11+
* This annotation ensures that the duration value of the annotated field does not exceed
12+
* the specified number of seconds. If the validation fails, a `SerializationException`
13+
* is thrown with a descriptive error message.
14+
*
15+
* @property seconds The maximum duration in seconds that the annotated field can have.
16+
*/
817
@Target(AnnotationTarget.FIELD)
918
@Retention(AnnotationRetention.RUNTIME)
1019
annotation class MaxDuration(val seconds: Long) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxLength.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Validates that a string config value does not exceed a specified maximum length.
9+
*
10+
* This annotation is used to ensure that the length of the annotated string
11+
* is less than or equal to the specified maximum value. If the validation fails,
12+
* a `SerializationException` is thrown with a descriptive error message.
13+
*
14+
* @property max The maximum allowed length for the string value.
15+
*/
716
@Target(AnnotationTarget.FIELD)
817
@Retention(AnnotationRetention.RUNTIME)
918
annotation class MaxLength(val max: Int) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MaxSize.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Specifies a maximum size constraint for collections, maps, arrays, or strings.
9+
*
10+
* This annotation enforces that the size or length of the annotated value does not exceed
11+
* the specified maximum. If the validation fails, a `SerializationException` is thrown
12+
* with a descriptive error message.
13+
*
14+
* @property max The maximum allowed size or length for the annotated value.
15+
*/
716
@Target(AnnotationTarget.FIELD)
817
@Retention(AnnotationRetention.RUNTIME)
918
annotation class MaxSize(val max: Int) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinDuration.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
55
import org.spongepowered.configurate.serialize.SerializationException
66
import java.lang.reflect.Type
77

8+
/**
9+
* Specifies a minimum duration constraint for configuration values annotated with this annotation.
10+
*
11+
* This annotation ensures that durations provided in the configuration meet or exceed
12+
* the specified minimum value in seconds. If the validation fails, a `SerializationException`
13+
* is thrown with a descriptive error message.
14+
*
15+
* @property seconds The minimum allowed duration in seconds.
16+
*/
817
@Target(AnnotationTarget.FIELD)
918
@Retention(AnnotationRetention.RUNTIME)
1019
annotation class MinDuration(val seconds: Long) {

surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/config/constraints/MinSize.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ import org.spongepowered.configurate.objectmapping.meta.Constraint
44
import org.spongepowered.configurate.serialize.SerializationException
55
import java.lang.reflect.Type
66

7+
/**
8+
* Specifies a minimum size constraint for collections, maps, arrays, or strings.
9+
*
10+
* This annotation enforces that the size or length of the annotated value is at least
11+
* the specified minimum. If the validation fails, a `SerializationException` is thrown
12+
* with a descriptive error message.
13+
*
14+
* @property min The minimum required size or length for the annotated value.
15+
*/
716
@Target(AnnotationTarget.FIELD)
817
@Retention(AnnotationRetention.RUNTIME)
918
annotation class MinSize(val min: Int) {

0 commit comments

Comments
 (0)