Skip to content

Commit

Permalink
allow custom error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusDunn committed Apr 3, 2024
1 parent 2a47f0c commit ab2fe47
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 63 deletions.
25 changes: 17 additions & 8 deletions values4k/src/main/kotlin/dev/forkhandles/values/ValueFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ abstract class ValueFactory<DOMAIN : Value<PRIMITIVE>, PRIMITIVE : Any>(
internal val coerceFn: (PRIMITIVE) -> DOMAIN,
private val validation: Validation<PRIMITIVE>? = null,
internal val parseFn: (String) -> PRIMITIVE,
internal val showFn: (PRIMITIVE) -> String = { it.toString() }
internal val showFn: (PRIMITIVE) -> String = { it.toString() },
internal val onInvalid: ValueFactory<DOMAIN, PRIMITIVE>.(PRIMITIVE, Exception) -> Nothing = { _, e -> defaultOnInvalid(e) },
internal val onParseFailure: ValueFactory<DOMAIN, PRIMITIVE>.(String, Exception) -> Nothing = { _, e -> defaultOnInvalid(e) }
) {
internal fun validate(value: PRIMITIVE): DOMAIN {
validation?.check(value)
Expand All @@ -17,21 +19,21 @@ abstract class ValueFactory<DOMAIN : Value<PRIMITIVE>, PRIMITIVE : Any>(
@Deprecated("Use of()", ReplaceWith("of(value)"))
operator fun invoke(value: PRIMITIVE): Any = error("invoke() factory method is not to be used for building microtypes - use of() instead!")

open fun parse(value: String) = attempt { validate(parseFn(value)) }
open fun parse(value: String): DOMAIN {
val parsed = attempt({ onParseFailure(value, it) }) { parseFn(value) }
return attempt({ onInvalid(parsed, it) }) { validate(parsed) }
}

fun show(value: DOMAIN) = showFn(unwrap(value))

open fun of(value: PRIMITIVE) = attempt { validate(value) }
open fun of(value: PRIMITIVE) = attempt({ onInvalid(value, it) }) { validate(value) }

fun unwrap(value: DOMAIN) = value.value

private fun <T> attempt(value: () -> T) = try {
private fun <T> attempt(onError: (Exception) -> Nothing, value: () -> T) = try {
value()
} catch (e: Exception) {
throw IllegalArgumentException(
this::class.java.name.substringBeforeLast('$') +
": " + e::class.java.name + " " + e.localizedMessage
)
onError(e)
}
}

Expand All @@ -46,3 +48,10 @@ fun <DOMAIN : Value<PRIMITIVE>, PRIMITIVE : Any> ValueFactory<DOMAIN, PRIMITIVE>

fun <DOMAIN : Value<PRIMITIVE>, PRIMITIVE : Any> ValueFactory<DOMAIN, PRIMITIVE>.showList(values: List<DOMAIN>) =
values.map(::show)

internal fun ValueFactory<*, *>.defaultOnInvalid(e: Exception): Nothing {
throw IllegalArgumentException(
this::class.java.name.substringBeforeLast('$') +
": " + e::class.java.name + " " + e.localizedMessage
)
}
Loading

0 comments on commit ab2fe47

Please sign in to comment.