All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.kotest.fp.Try.kt Maven / Gradle / Ivy

There is a newer version: 4.0.7
Show newest version
package io.kotest.fp

sealed class Try {

   data class Success(val value: T) : Try()
   data class Failure(val error: Throwable) : Try()

   companion object {
      operator fun invoke(t: Throwable): Try = Failure(t)
      inline operator fun  invoke(f: () -> T): Try = try {
         Success(f())
      } catch (e: Throwable) {
         println(e)
         if (nonFatal(e)) Failure(e) else throw e
      }
   }

   inline fun  map(f: (T) -> U): Try = flatMap {
      Try { f(it) }
   }

   fun isSuccess() = this is Success
   fun isFailure() = this is Failure

   fun getOrThrow(): T = when (this) {
      is Failure -> throw error
      is Success -> value
   }

   inline fun  flatMap(f: (T) -> Try): Try = when (this) {
      is Failure -> this
      is Success -> f(value)
   }

   inline fun  fold(ifFailure: (Throwable) -> R, ifSuccess: (T) -> R): R = when (this) {
      is Failure -> ifFailure(this.error)
      is Success -> ifSuccess(this.value)
   }

   inline fun onFailure(f: (Throwable) -> Unit): Try = when (this) {
      is Success -> this
      is Failure -> {
         f(this.error)
         this
      }
   }

   inline fun onSuccess(f: (T) -> Unit): Try = when (this) {
      is Success -> {
         f(this.value)
         this
      }
      is Failure -> this
   }

   fun toOption(): Option = fold({ Option.None }, {
      Option.Some(
         it
      )
   })

   inline fun mapFailure(f: (Throwable) -> Throwable) = fold({ f(it).failure() }, { it.success() })

   fun getOrNull(): T? = fold({ null }, { it })
}

fun  Try>.flatten(): Try = when (this) {
   is Try.Success -> this.value
   is Try.Failure -> this
}

inline fun  Try.getOrElse(f: (Throwable) -> U): U = when (this) {
   is Try.Success -> this.value
   is Try.Failure -> f(this.error)
}

inline fun  Try.recoverWith(f: (Throwable) -> Try): Try = when (this) {
   is Try.Success -> this
   is Try.Failure -> f(this.error)
}

fun  Try.recover(f: (Throwable) -> U): Try = when (this) {
   is Try.Success -> this
   is Try.Failure -> Try { f(this.error) }
}

fun  T.success(): Try = Try.Success(this)
fun Throwable.failure(): Try = Try.Failure(this)

expect fun nonFatal(t: Throwable): Boolean