Skip to content

Commit 45ec6d1

Browse files
committed
⚡️: optimize the function calling experience when Either is used as a parameter
1 parent 26bd7f8 commit 45ec6d1

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

app/src/main/java/xyz/junerver/composehooks/example/UseCounterExample.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import androidx.compose.material3.Surface
66
import androidx.compose.material3.Text
77
import androidx.compose.runtime.Composable
88
import arrow.core.left
9+
import arrow.core.right
10+
import xyz.junerver.compose.hooks.invoke
911
import xyz.junerver.compose.hooks.optionsOf
1012
import xyz.junerver.compose.hooks.useCounter
1113
import xyz.junerver.composehooks.ui.component.TButton
@@ -21,7 +23,7 @@ import xyz.junerver.composehooks.ui.component.TButton
2123
@Composable
2224
fun UseCounterExample() {
2325
val (current, inc, dec, set, reset) = useCounter(
24-
initialValue = 100,
26+
initialValue = 100, //即使配置了100也不会超出选项的上下限
2527
options = optionsOf {
2628
min = 1
2729
max = 10
@@ -39,7 +41,25 @@ fun UseCounterExample() {
3941
dec(1)
4042
}
4143
TButton(text = "set(3)") {
42-
set(3.left())
44+
/**
45+
* 这里如果你想传入的是数值则使用 [left] 函数, 如果想传入的是函数 则使用 [right] 函数。
46+
* 也可以手动导入[invoke]来优化使用体验。
47+
*
48+
* Here, if you want to pass in a numerical value, use the [left] function.
49+
* If you want to pass in a function, use the [right] function. You
50+
* can also manually import [invoke] to optimize the user experience.
51+
*
52+
* ```
53+
* set(3.left())
54+
* set({value:Int ->
55+
* value/3
56+
* }.right())
57+
* ```
58+
*/
59+
set(3)
60+
}
61+
TButton(text = "set(/3)") {
62+
set { value: Int -> value / 3 }
4363
}
4464
TButton(text = "reset()") {
4565
reset()

hooks/src/main/kotlin/xyz/junerver/compose/hooks/useCounter.kt

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,35 @@ data class CounterOptions internal constructor(
2424
internal typealias IncFn = (Int) -> Unit
2525
internal typealias DecFn = (Int) -> Unit
2626

27+
/**
28+
* Use counter
29+
*
30+
* @param initialValue initial value of count
31+
* @param options
32+
* @return
33+
*
34+
* 在使用第三个解构值[SetValueFn]时,如果你想传入的是数值则使用 [left] 函数, 如果想传入的是函数 则使用 [right]
35+
* 函数,也可以手动导入[invoke]来优化使用体验。
36+
*
37+
* When using the third destructured value [SetValueFn], if you want to
38+
* pass in a numerical value, use the [left] function. If you want to pass
39+
* in a function, use the [right] function. You can also manually import
40+
* [invoke] to optimize the user experience.
41+
*
42+
* ```
43+
* set(3.left())
44+
* set({value:Int ->
45+
* value/3
46+
* }.right())
47+
* ```
48+
*/
2749
@Composable
28-
fun useCounter(initialValue: Int = 0, options: CounterOptions): Tuple5<Int, IncFn, DecFn, SetValueFn<Either<Int, (Int) -> Int>>, ResetFn> {
50+
fun useCounter(
51+
initialValue: Int = 0,
52+
options: CounterOptions,
53+
): Tuple5<Int, IncFn, DecFn, SetValueFn<Either<Int, (Int) -> Int>>, ResetFn> {
2954
val (current, setCurrent, getCurrent) = useGetState(getTargetValue(initialValue, options))
30-
fun setValue(value: Either<Int, (Int) -> Int>) {
55+
val setValue: SetValueFn<Either<Int, (Int) -> Int>> = { value: Either<Int, (Int) -> Int> ->
3156
val target = value.fold(
3257
ifLeft = { it },
3358
ifRight = { it(getCurrent()) }
@@ -36,18 +61,19 @@ fun useCounter(initialValue: Int = 0, options: CounterOptions): Tuple5<Int, IncF
3661
}
3762

3863
fun inc(delta: Int) {
39-
setValue({ c: Int -> c + delta }.right())
64+
setValue { c: Int -> c + delta }
4065
}
4166

4267
fun dec(delta: Int) {
43-
setValue({ c: Int -> c - delta }.right())
68+
setValue { c: Int -> c - delta }
4469
}
4570

4671
fun set(value: Either<Int, (Int) -> Int>) {
4772
setValue(value)
4873
}
74+
4975
fun reset() {
50-
setValue(initialValue.left())
76+
setValue(initialValue)
5177
}
5278

5379
return Tuple5(
@@ -63,3 +89,7 @@ private fun getTargetValue(value: Int, options: CounterOptions): Int {
6389
val (min, max) = options
6490
return value.coerceIn(min, max)
6591
}
92+
93+
operator fun SetValueFn<Either<Int, (Int) -> Int>>.invoke(leftValue: Int) = this(leftValue.left())
94+
operator fun SetValueFn<Either<Int, (Int) -> Int>>.invoke(rightValue: (Int) -> Int) =
95+
this(rightValue.right())

0 commit comments

Comments
 (0)