
Type-safe, fluent validation DSL for expressive, composable rules with zero-reflection performance, modular extensibility, detailed error reporting, fail-fast or collect-all modes, and optional datetime validators.
A modern, type-safe validation library for Kotlin Multiplatform that makes data validation elegant, readable, and maintainable.
[!IMPORTANT] Full documentation website coming soon
Add the dependencies to your build.gradle.kts:
dependencies {
// Core validation library
implementation("dev.megatilus.atelier:validator-core:${version}")
// Optional: kotlinx-datetime integration
implementation("dev.megatilus.atelier:validator-kotlinx-datetime:${version}")
}Define your data class and create a validator:
data class User(
val name: String,
val email: String,
val password: String,
val age: Int,
val tags: List<String>
)
val userValidator = atelierValidator<User> {
User::name {
notBlank()
minLength(2)
maxLength(50)
}
User::email {
notBlank()
email()
}
User::password {
notBlank()
strongPassword()
}
User::age {
range(18, 120)
}
User::tags {
notEmpty()
minSize(1)
maxSize(5)
}
}val user = User(
name = "John Doe",
email = "john@example.com",
password = "SecureP@ss123",
age = 25,
tags = listOf("developer", "kotlin")
)
val result = userValidator.validate(user)
when (result) {
is ValidationResult.Success -> println("β
Validation successful!")
is ValidationResult.Failure -> {
result.errors.forEach { error ->
println("β ${error.fieldName}: ${error.message}")
}
}
}Or with detailed output:
if (result is ValidationResult.Failure) {
result.errors.forEach { error ->
println("Field: ${error.fieldName}")
println("Message: ${error.message}")
println("Code: ${error.code}")
println("Actual Value: ${error.actualValue}")
}
}Atelier provides built-in validators for common types:
Strings: notBlank(), email(), url(), phoneNumber(), creditCard(), strongPassword(), matches(), alphanumeric(), and more
Numbers: positive(), negative(), min(), max(), range(), between(), isGreaterThan(), isLessThan(), and more
Collections: notEmpty(), size(), contains(), containsAll(), minSize(), maxSize(), and more
Dates (kotlinx-datetime): isBefore(), isAfter(), isBetween(), isToday(), and more
π Full documentation website coming soon!
For now, explore all available validators through IDE autocomplete or browse the source code.
For validator-kotlinx-datetime, see the source code.
Define custom validators effortlessly:
fun <T : Any> FieldValidatorBuilder<T, String>.username(
message: String? = null
): FieldValidatorBuilder<T, String> =
constraintForExtension(
hint = message ?: "Invalid username format",
code = ValidatorCode.INVALID_FORMAT,
predicate = {
it.length in 3..20 &&
it.all { c -> c.isLetterOrDigit() || c == '_' || c == '-' }
}
)
// Usage
val validator = atelierValidator<User> {
User::username {
username()
}
}Returns all validation errors
val result = validator.validate(user)Stops at the first validation error
val result = validator.validateFirst(user)Each validation error provides comprehensive context:
data class ValidationErrorDetail(
val fieldName: String, // e.g., "email"
val message: String, // e.g., "Invalid email format"
val code: ValidatorCode, // e.g., ValidatorCode.INVALID_FORMAT
val actualValue: String // The actual value that failed validation
)when (result) {
is ValidationResult.Failure -> {
val allErrors = result.errors
val emailErrors = result.errorsFor("email")
val firstError = result.firstErrorFor("email")
val errorsByField = result.errorsByField
val count = result.errorCount
}
}Core validation library with standard validators for strings, numbers, collections, booleans, arrays, sets, and maps.
Extension module providing date and time validators based on kotlinx-datetime.
Contributions are welcome!
A modern, type-safe validation library for Kotlin Multiplatform that makes data validation elegant, readable, and maintainable.
[!IMPORTANT] Full documentation website coming soon
Add the dependencies to your build.gradle.kts:
dependencies {
// Core validation library
implementation("dev.megatilus.atelier:validator-core:${version}")
// Optional: kotlinx-datetime integration
implementation("dev.megatilus.atelier:validator-kotlinx-datetime:${version}")
}Define your data class and create a validator:
data class User(
val name: String,
val email: String,
val password: String,
val age: Int,
val tags: List<String>
)
val userValidator = atelierValidator<User> {
User::name {
notBlank()
minLength(2)
maxLength(50)
}
User::email {
notBlank()
email()
}
User::password {
notBlank()
strongPassword()
}
User::age {
range(18, 120)
}
User::tags {
notEmpty()
minSize(1)
maxSize(5)
}
}val user = User(
name = "John Doe",
email = "john@example.com",
password = "SecureP@ss123",
age = 25,
tags = listOf("developer", "kotlin")
)
val result = userValidator.validate(user)
when (result) {
is ValidationResult.Success -> println("β
Validation successful!")
is ValidationResult.Failure -> {
result.errors.forEach { error ->
println("β ${error.fieldName}: ${error.message}")
}
}
}Or with detailed output:
if (result is ValidationResult.Failure) {
result.errors.forEach { error ->
println("Field: ${error.fieldName}")
println("Message: ${error.message}")
println("Code: ${error.code}")
println("Actual Value: ${error.actualValue}")
}
}Atelier provides built-in validators for common types:
Strings: notBlank(), email(), url(), phoneNumber(), creditCard(), strongPassword(), matches(), alphanumeric(), and more
Numbers: positive(), negative(), min(), max(), range(), between(), isGreaterThan(), isLessThan(), and more
Collections: notEmpty(), size(), contains(), containsAll(), minSize(), maxSize(), and more
Dates (kotlinx-datetime): isBefore(), isAfter(), isBetween(), isToday(), and more
π Full documentation website coming soon!
For now, explore all available validators through IDE autocomplete or browse the source code.
For validator-kotlinx-datetime, see the source code.
Define custom validators effortlessly:
fun <T : Any> FieldValidatorBuilder<T, String>.username(
message: String? = null
): FieldValidatorBuilder<T, String> =
constraintForExtension(
hint = message ?: "Invalid username format",
code = ValidatorCode.INVALID_FORMAT,
predicate = {
it.length in 3..20 &&
it.all { c -> c.isLetterOrDigit() || c == '_' || c == '-' }
}
)
// Usage
val validator = atelierValidator<User> {
User::username {
username()
}
}Returns all validation errors
val result = validator.validate(user)Stops at the first validation error
val result = validator.validateFirst(user)Each validation error provides comprehensive context:
data class ValidationErrorDetail(
val fieldName: String, // e.g., "email"
val message: String, // e.g., "Invalid email format"
val code: ValidatorCode, // e.g., ValidatorCode.INVALID_FORMAT
val actualValue: String // The actual value that failed validation
)when (result) {
is ValidationResult.Failure -> {
val allErrors = result.errors
val emailErrors = result.errorsFor("email")
val firstError = result.firstErrorFor("email")
val errorsByField = result.errorsByField
val count = result.errorCount
}
}Core validation library with standard validators for strings, numbers, collections, booleans, arrays, sets, and maps.
Extension module providing date and time validators based on kotlinx-datetime.
Contributions are welcome!