Skip to content

Instantly share code, notes, and snippets.

@Grohden
Last active March 14, 2019 13:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grohden/31f34a960792741d1c35478762e332b4 to your computer and use it in GitHub Desktop.
Save Grohden/31f34a960792741d1c35478762e332b4 to your computer and use it in GitHub Desktop.
My common extension functions for kotlin
/**
* Forks a nullable into a non nullable,
*
* This differs from the if else expression
* which is thread unsafe and doesn't guarantee
* the non nullability even if the value was validated as non null
* by the if expression (due to concurrency)
* NOTE: need to check this :D, probably i need to use contracts like the std to assure what
* i said above
*
* @param whenPresent a function to be executed when the value is present
* @param whenAbsent a function to be executed when the value is absent
*
* @return a value R that should not be null
*/
inline fun <T, R> T?.fork(whenPresent: (T) -> R, whenAbsent: () -> R): R {
this.let {
return if (this != null) {
whenPresent(this)
} else {
whenAbsent()
}
}
}
// Simillar to the fork function
// https://www.reddit.com/r/Kotlin/comments/8k1885/why_cant_the_else_part_of_let_take_a_block/dz4br77
// And yes, this function works, but imagine this :
// val result = str.let{ "Foo" }.orElse{ "Bar" }
// will compile fine.. but the else part is useless cuz we forgot the ?.let part,
// and the compiler will not warn use about that
// ==================================================================================================
// inline fun <R> R?.orElse(block: () -> R): R {
// return this ?: block()
// }
/**
* Applies a function when the predicate returns true
*
* @param predicate the predicate
* @param whenTrue the function to call when the predicate returns true,
* the return value of this function is used when the predicate is true
*
* @return the result of the whenTrue function or this if the predicate is false
*/
inline fun <T> T.applyWhen(predicate: (T) -> Boolean, whenTrue: T.() -> T): T {
this.let {
return if (predicate(this)) {
whenTrue()
} else {
this
}
}
}
/**
* Applies a function when the predicate returns true
*
* @param predicate the predicate
* @param whenTrue the function to call when the predicate returns true,
* the return value of this function is used when the predicate is true
*
* @return the result of the whenTrue function or this if the predicate is false
*/
inline fun <T> T.letWhen(predicate: (T) -> Boolean, whenTrue: (T) -> T): T {
this.let {
return if (predicate(this)) {
whenTrue(this)
} else {
this
}
}
}
/**
* Applies a lambda when the boolean value is true
*
* @param block the lambda to be executed when the boolean is true
*
* @return null when false otherwise the result of the block execution
*/
inline fun <T> Boolean.whenTrue(block: (Boolean) -> T): T? = takeIf { this }?.let(block)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment