dev.forkhandles.values.ValueFactory.kt Maven / Gradle / Ivy
package dev.forkhandles.values
/**
* Base value type for inline classes which enables type-safe primitives, along with Validation.
*/
abstract class ValueFactory, PRIMITIVE : Any>(
internal val coerceFn: (PRIMITIVE) -> DOMAIN,
private val validation: Validation? = null,
internal val parseFn: (String) -> PRIMITIVE,
internal val showFn: (PRIMITIVE) -> String = { it.toString() }
) {
internal fun validate(value: PRIMITIVE): DOMAIN {
validation?.check(value)
return coerceFn(value)
}
@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)) }
fun show(value: DOMAIN) = showFn(unwrap(value))
open fun of(value: PRIMITIVE) = attempt { validate(value) }
fun unwrap(value: DOMAIN) = value.value
private fun attempt(value: () -> T) = try {
value()
} catch (e: Exception) {
throw IllegalArgumentException(
this::class.java.name.substringBeforeLast('$') +
": " + e::class.java.name + " " + e.localizedMessage
)
}
}
fun , PRIMITIVE : Any> ValueFactory.ofList(vararg values: PRIMITIVE) =
values.map(::of)
fun , PRIMITIVE : Any> ValueFactory.parseList(vararg values: String) =
values.map(::parse)
fun , PRIMITIVE : Any> ValueFactory.showList(vararg values: DOMAIN) =
showList(values.toList())
fun , PRIMITIVE : Any> ValueFactory.showList(values: List) =
values.map(::show)