Skip to content

nesk/akkurate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Akkurate

Get started by reading the documentation

Akkurate is a validation library taking advantage of the expressive power of Kotlin. No need
for 30+ annotations or complicated custom constraints; write your validation code in Kotlin with a beautiful declarative API.

Designed from scratch to handle complex business logic, its role is to help you write qualitative and maintainable validation code.

A code example of Akkurate used to showcase the library on social networks.

Warning

Akkurate is under development and, despite being heavily tested, its API isn't yet stabilized; breaking changes might happen on minor releases. However, we will always provide migration guides.

Report any issue or bug in the GitHub repository.

Showcase

Here's an example showcasing how you can constrain a book and its list of authors.

// Define your classes

@Validate
data class Book(
    val title: String,
    val releaseDate: LocalDateTime,
    val authors: List<Author>,
)

@Validate
data class Author(val firstName: String, val lastName: String)

// Write your validation rules

val validateBook = Validator<Book> {
    // First the property, then the constraint, finally the message.
    title.isNotEmpty() otherwise { "Missing title" }

    releaseDate.isInPast() otherwise { "Release date must be in past" }

    authors.hasSizeBetween(1..10) otherwise { "Wrong author count" }

    authors.each { // Apply constraints to each author
        (firstName and lastName) {
            // Apply the same constraint to both properties
            isNotEmpty() otherwise { "Missing name" }
        }
    }
}

// Validate your data

when (val result = validateBook(someBook)) {
    is Success -> println("Success: ${result.value}")
    is Failure -> {
        val list = result.violations
            .joinToString("\n") { "${it.path}: ${it.message}" }
        println("Failures:\n$list")
    }
}

Notice how each constraint applied to a property can be read like a sentence. This code:

title.isNotEmpty() otherwise { "Missing title" }

can be read:

Check if 'title' is not empty otherwise write "Missing title".

Features