Skip to content

Commit 515084a

Browse files
authored
Merge pull request #279 from robstoll/feature/runIf
add also/apply/run to complement the series and a prefix takeUnless
2 parents 1f38455 + 9b8f74c commit 515084a

File tree

4 files changed

+97
-24
lines changed

4 files changed

+97
-24
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
-->
1414

1515
# KBox
16+
1617
KBox is a very small but useful utility library for Kotlin (JVM, Android and JS) providing functions which are missing
1718
in the stdlib such as:
19+
1820
- [failIf](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/failIf.kt)
19-
- [takeIf](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/takeIf.kt)
21+
- [prefix takeIf/takeUnless](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/takeIf.kt)
22+
- [letIf/runIf/alsoIf/applyIf](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/xyzIf.kt)
2023
- [blankToNull](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/blankToNull.kt)
2124
- [isNotNullAndNotEmpty/Blank](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/isNotNullAndNot.kt)
2225
- [identity](https://github.com/robstoll/kbox/tree/main/src/commonMain/kotlin/ch/tutteli/kbox/identity.kt)
@@ -42,6 +45,6 @@ dependencies {
4245

4346
Visit [https://robstoll.github.io/kbox/kdoc](https://robstoll.github.io/kbox/kdoc/).
4447

45-
4648
# License
49+
4750
KBox is licensed under [Apache 2.0](http://opensource.org/licenses/Apache2.0).

src/commonMain/kotlin/ch/tutteli/kbox/takeIf.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import kotlin.contracts.contract
1818
inline fun <R> takeIf(predicate: Boolean, provider: () -> R): R? {
1919
contract {
2020
callsInPlace(provider, InvocationKind.AT_MOST_ONCE)
21+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
2122
}
2223
return if (predicate) provider() else null
2324
}

src/commonMain/kotlin/ch/tutteli/kbox/xIf.kt

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package ch.tutteli.kbox
2+
3+
import kotlin.contracts.ExperimentalContracts
4+
import kotlin.contracts.InvocationKind
5+
import kotlin.contracts.contract
6+
7+
/**
8+
* Delegates to [let] in case the given [predicate] holds, returns `this` otherwise.
9+
*
10+
* This function shall complement [let] for cases such as invoking a builder method conditionally which without [letIf]
11+
* would be written as follows `if (predicate) t.let { ... } else t`
12+
*
13+
* @since 3.2.0
14+
*/
15+
@OptIn(ExperimentalContracts::class)
16+
inline fun <T : U, R : U, U> T.letIf(predicate: Boolean, block: (T) -> R): U {
17+
contract {
18+
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
19+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
20+
}
21+
return if (predicate) let(block) else this
22+
}
23+
24+
/**
25+
* Delegates to [run] in case the given [predicate] holds, returns `this` otherwise.
26+
*
27+
* This function shall complement [run] for cases such as invoking a builder method conditionally which without [runIf]
28+
* would be written as follows `if (predicate) t.run { ... } else t`
29+
*
30+
* @since 3.2.0
31+
*/
32+
@OptIn(ExperimentalContracts::class)
33+
inline fun <T : U, R : U, U> T.runIf(predicate: Boolean, block: T.() -> R): U {
34+
contract {
35+
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
36+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
37+
}
38+
return if (predicate) run(block) else this
39+
}
40+
41+
/**
42+
* Delegates to [also] in case the given [predicate] holds, returns `this` otherwise.
43+
*
44+
* This function shall complement [also] and make simple conditional based side effects more readable.
45+
*
46+
* @since 3.2.0
47+
*/
48+
@OptIn(ExperimentalContracts::class)
49+
inline fun <T> T.alsoIf(predicate: Boolean, block: (T) -> Unit): T {
50+
contract {
51+
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
52+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
53+
}
54+
return if (predicate) also(block) else this
55+
}
56+
57+
/**
58+
* Delegates to [apply] in case the given [predicate] holds, returns `this` otherwise.
59+
*
60+
* This function shall complement [apply] and make simple conditional based side effects more readable.
61+
*
62+
* @since 3.2.0
63+
*/
64+
@OptIn(ExperimentalContracts::class)
65+
inline fun <T> T.applyIf(predicate: Boolean, block: T.() -> Unit): T {
66+
contract {
67+
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
68+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
69+
}
70+
return if (predicate) apply(block) else this
71+
}
72+
73+
/**
74+
* Returns `null` if the [predicate] holds, calls the [provider] otherwise.
75+
*
76+
* This function shall complement [kotlin.takeUnless] for cases where the cost to call the provider
77+
* is high or the code involved to define the provider is long and a postfix `takeUnless` is less readable
78+
* than stating it at the beginning.
79+
*
80+
* @since 3.2.0
81+
*/
82+
//TODO move to xIf with 4.0.0
83+
@OptIn(ExperimentalContracts::class)
84+
inline fun <R> takeUnless(predicate: Boolean, provider: () -> R): R? {
85+
contract {
86+
callsInPlace(provider, InvocationKind.AT_MOST_ONCE)
87+
//TODO add `predicate holds in block` once we use Kotlin 2.2.20
88+
}
89+
return if (predicate.not()) provider() else null
90+
}
91+

0 commit comments

Comments
 (0)