47 lines
1.2 KiB
Kotlin
47 lines
1.2 KiB
Kotlin
|
@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS", "UNCHECKED_CAST")
|
||
|
inline class Option<A> private constructor(val value: Any?) {
|
||
|
|
||
|
inline fun <R> map(op: (A) -> R): Option<R> =
|
||
|
if (this.value === EmptyOptionValue) {
|
||
|
this as Option<R>
|
||
|
} else {
|
||
|
Option.just(op(this.value as A))
|
||
|
}
|
||
|
|
||
|
inline fun filter(op: (A) -> Boolean): Option<A> =
|
||
|
if (this.value === EmptyOptionValue || !op(this.value as A)) {
|
||
|
none()
|
||
|
} else {
|
||
|
this
|
||
|
}
|
||
|
|
||
|
inline fun <R> fold(ifPresent: (A) -> R, ifEmpty: () -> R): R =
|
||
|
if (this.value === EmptyOptionValue) {
|
||
|
ifEmpty()
|
||
|
} else {
|
||
|
ifPresent(this.value as A)
|
||
|
}
|
||
|
|
||
|
fun getOrNull(): A? =
|
||
|
if (this.value === EmptyOptionValue) {
|
||
|
null
|
||
|
} else {
|
||
|
this.value as A
|
||
|
}
|
||
|
|
||
|
companion object {
|
||
|
private val EMPTY = Option<Any>(EmptyOptionValue)
|
||
|
|
||
|
fun <A> none() = EMPTY as Option<A>
|
||
|
|
||
|
fun <A> just(value: A) = Option<A>(value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Marker for empty options.
|
||
|
* This is necessary to allow nullable types in the option.
|
||
|
* TODO: Somehow don’t expose this.
|
||
|
*/
|
||
|
object EmptyOptionValue
|