Common kotlin extensions

Common Kotlin extension functions for several tasks.

Also check out the dedicated pages:

General

inline fun <T, R> T.letIf(predicate: (T) -> Boolean, block: (T) -> R): R? = if (predicate.invoke(this)) block(this) else null

/**
 * The opposite of using `?.let { }` is using `.elseLet{ }`
 */ 
fun Any?.elseLet(block: () -> Unit) {
    if (this == null) {
        block()
    }
}

inline fun catchAll(message: String = "", action: () -> Unit) =
        try {
            action()
        } catch (t: Throwable) {
            Log.e("Exception", if (message.isNotBlank()) message else t.message, t)
        }

fun printStackTrace() =
        try {
            throw RuntimeException()
        } catch (e: Exception) {
            e.printStackTrace()
        }

/**
 * For resources that throw exception when invoked like LinkedList#getLast()
 */
fun <T> T.getOrNull(): T? = try {
    this
} catch (t: Throwable) {
    null
}

fun benchmark(operation: String, code: () -> Unit, onlyLogWhenExcessMs: Int = 12) {
    if (BuildConfig.DEBUG) {
        val start = System.nanoTime()
        code()
        val durationMs = (System.nanoTime() - start) / 1000000f
        if (durationMs > onlyLogWhenExcessMs)
            Log.w("BENCHMARK", String.format("$operation %.1fms", durationMs))
    } else {
        code()
    }
}

File I/O

/**
 * Opens an InputStream to the specified path.
 * Pro tip: By prefixing `raw/` or `res/raw/` to the String you can load files from res/raw without a Context (Android only).
 */
fun String.openStream(clz: Any) = clz.javaClass.classLoader?.getResourceAsStream(this)

fun InputStream.readFile() = this.bufferedReader().use(BufferedReader::readText)

fun String.readFile(clz: Any) = this.openStream(clz)?.readFile()