Skip to content

Instantly share code, notes, and snippets.

@nakamura-to
Last active December 13, 2025 13:37
Show Gist options
  • Select an option

  • Save nakamura-to/8e2e8900a8a9ffdea036ac88dc3c3dab to your computer and use it in GitHub Desktop.

Select an option

Save nakamura-to/8e2e8900a8a9ffdea036ac88dc3c3dab to your computer and use it in GitHub Desktop.
Kovaを使ってParse don't Validateの実現
package example
import org.komapper.extension.validator.Kova
import org.komapper.extension.validator.ObjectSchema
import org.komapper.extension.validator.ValidationResult
import org.komapper.extension.validator.factory.generateFactory
import org.komapper.extension.validator.factory.tryCreate
import org.komapper.extension.validator.isInt
import org.komapper.extension.validator.isNullOr
import org.komapper.extension.validator.isSuccess
import org.komapper.extension.validator.max
import org.komapper.extension.validator.min
import org.komapper.extension.validator.notNull
import org.komapper.extension.validator.then
import org.komapper.extension.validator.toInt
import org.komapper.extension.validator.toNonNullable
// このサンプルコードは以下のページにあるJava版のコードをKotlinのライブラリ(https://github.com/komapper/kova)を使って書き換えたものです
// https://scrapbox.io/kawasima/バリデーション解体新書
data class ReserveTourInput(
val tourCode: String,
val adultCount: Int,
val childCount: Int,
val remarks: String?,
) {
companion object : ObjectSchema<ReserveTourInput>() {
private val intStringValidator = Kova.nullable<String>().notNull().toNonNullable().then { it.isInt().toInt() }
private val countValidator = Kova.int().min(0).max(5)
fun parse(tourCode: String, adultCount: String?, childCount: String?, remarks: String?): ValidationResult<ReserveTourInput> {
val factory = generateFactory("ReserveTourInput") {
val tourCode = check("tourCode", tourCode) { it.min(1).max(10) }
val adultCount = check("adultCount", adultCount) { intStringValidator.then(countValidator) }
val childCount = check("childCount", childCount) { intStringValidator.then(countValidator) }
val remarks = check("remarks", remarks) { it.isNullOr({ it.min(0).max(80)}) }
create { ReserveTourInput(tourCode(), adultCount(), childCount(), remarks()) }
}
return factory.tryCreate()
}
}
}
fun main() {
println("検証成功の例")
val result1 = ReserveTourInput.parse("123", "2", "3", "remarks")
if (result1.isSuccess()) {
println(result1.value)
// ReserveTourInput(tourCode=123, adultCount=2, childCount=3, remarks=remarks)
} else {
error("never happens")
}
println("検証失敗の例")
val result2 = ReserveTourInput.parse("", "10", "-1", "remarks")
if (result2.isSuccess()) {
error("never happens")
} else {
println(result2.messages.joinToString("\n"))
// Message(constraintId=kova.charSequence.min, text='must be at least 1 characters', root=ReserveTourInput, path=tourCode, input=)
// Message(constraintId=kova.comparable.max, text='must be less than or equal to 5', root=ReserveTourInput, path=adultCount, input=10)
// Message(constraintId=kova.comparable.min, text='must be greater than or equal to 0', root=ReserveTourInput, path=childCount, input=-1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment