@@ -34,7 +34,7 @@ import kotlin.jvm.JvmName
34
34
* the operators that are invoked are called **immediately** and in-place.
35
35
*/
36
36
@JvmInline
37
- public value class ApiResult <out T > @PublishedApi internal constructor(@PublishedApi internal val value : Any? ) {
37
+ public value class ApiResult <out T > private constructor(@PublishedApi internal val value : Any? ) {
38
38
39
39
/* *
40
40
* Get the [Success] component of this result or null
@@ -45,7 +45,7 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
45
45
* ```
46
46
* @see orNull
47
47
*/
48
- public operator fun component1 (): T ? = orNull()
48
+ public inline operator fun component1 (): T ? = orNull()
49
49
50
50
/* *
51
51
* Get the [Error] component of this result or null
@@ -56,27 +56,35 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
56
56
* ```
57
57
* @see exceptionOrNull
58
58
*/
59
- public operator fun component2 (): Exception ? = exceptionOrNull()
59
+ public inline operator fun component2 (): Exception ? = exceptionOrNull()
60
60
61
61
/* *
62
62
* Bang operator returns the result or throws if it is an [Error] or [Loading]
63
63
* This is equivalent to calling [orThrow]
64
64
*/
65
- public operator fun not (): T = orThrow()
65
+ public inline operator fun not (): T = orThrow()
66
66
67
67
/* *
68
68
* The state of [ApiResult] that represents an error.
69
69
* @param e wrapped [Exception]
70
70
*/
71
71
@JvmInline
72
72
@PublishedApi
73
- internal value class Error (@JvmField val e : Exception ) {
73
+ internal value class Error private constructor (@JvmField val e : Exception ) {
74
74
75
75
override fun toString (): String = " ApiResult.Error: message=${e.message} and cause: $e "
76
+
77
+ companion object {
78
+
79
+ fun create (e : Exception ) = Error (e)
80
+ }
76
81
}
77
82
78
83
@PublishedApi
79
- internal data object Loading
84
+ internal data object Loading {
85
+
86
+ override fun toString (): String = " ApiResult.Loading"
87
+ }
80
88
81
89
/* *
82
90
* Whether this is [Success]
@@ -91,10 +99,10 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
91
99
/* *
92
100
* Whether this is [Loading]
93
101
*/
94
- public inline val isLoading: Boolean get() = value is Loading
102
+ public inline val isLoading: Boolean get() = value == = Loading
95
103
96
104
override fun toString (): String = when {
97
- value is Error || value is Loading -> value.toString()
105
+ value is Error || value == = Loading -> value.toString()
98
106
else -> " ApiResult.Success: $value "
99
107
}
100
108
@@ -103,17 +111,17 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
103
111
/* *
104
112
* Create a successful [ApiResult] value
105
113
*/
106
- public inline fun <T > Success (value : T ): ApiResult <T > = ApiResult (value)
114
+ public fun <T > Success (value : T ): ApiResult <T > = ApiResult (value = value)
107
115
108
116
/* *
109
117
* Create an error [ApiResult] value
110
118
*/
111
- public inline fun <T > Error (value : Exception ): ApiResult <T > = ApiResult (Error (e = value ))
119
+ public fun <T > Error (e : Exception ): ApiResult <T > = ApiResult (value = Error .create (e = e ))
112
120
113
121
/* *
114
122
* Create a loading [ApiResult] value
115
123
*/
116
- public inline fun <T > Loading (): ApiResult <T > = ApiResult (value = Loading )
124
+ public fun <T > Loading (): ApiResult <T > = ApiResult (value = Loading )
117
125
118
126
/* *
119
127
* Create an [ApiResult] instance using the given value.
@@ -123,7 +131,7 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
123
131
* If you want to directly create a success value of an [Exception], use [Success]
124
132
*/
125
133
public inline operator fun <T > invoke (value : T ): ApiResult <T > = when (value) {
126
- is Exception -> Error (value = value)
134
+ is Exception -> Error (e = value)
127
135
else -> Success (value)
128
136
}
129
137
@@ -135,11 +143,11 @@ public value class ApiResult<out T> @PublishedApi internal constructor(@Publishe
135
143
* [CancellationException]s are rethrown.
136
144
*/
137
145
public inline operator fun <T > invoke (call : () -> T ): ApiResult <T > = try {
138
- Success (call())
146
+ Success (value = call())
139
147
} catch (e: CancellationException ) {
140
148
throw e
141
149
} catch (expected: Exception ) {
142
- Error (expected)
150
+ Error (e = expected)
143
151
}
144
152
145
153
/* *
@@ -195,10 +203,13 @@ public inline infix fun <T, R : T> ApiResult<T>.orElse(block: (e: Exception) ->
195
203
}
196
204
197
205
/* *
198
- * If [this] is [Error], returns [defaultValue].
206
+ * If [this] is [Error] or [Loading] , returns [defaultValue].
199
207
* @see orElse
200
208
*/
201
- public inline infix fun <T , R : T > ApiResult<T>.or (defaultValue : R ): T = orElse { defaultValue }
209
+ public inline infix fun <T , R : T > ApiResult<T>.or (defaultValue : R ): T = when (value) {
210
+ is Error , is Loading -> defaultValue
211
+ else -> value as T
212
+ }
202
213
203
214
/* *
204
215
* @return null if [this] is an [ApiResult.Error] or [ApiResult.Loading], otherwise return self.
@@ -312,7 +323,9 @@ public inline fun <T> ApiResult<T>.errorIf(
312
323
callsInPlace(predicate, InvocationKind .AT_MOST_ONCE )
313
324
callsInPlace(exception, InvocationKind .AT_MOST_ONCE )
314
325
}
315
- return if (isSuccess && predicate(value as T )) Error (value = exception()) else this
326
+ if (! isSuccess) return this
327
+ if (! predicate(value as T )) return this
328
+ return Error (e = exception())
316
329
}
317
330
318
331
/* *
@@ -326,7 +339,7 @@ public inline fun <T> ApiResult<T>.errorOnLoading(
326
339
}
327
340
328
341
return when (value) {
329
- is Loading -> Error (value = exception())
342
+ is Loading -> Error (e = exception())
330
343
else -> this
331
344
}
332
345
}
@@ -337,10 +350,10 @@ public inline fun <T> ApiResult<T>.errorOnLoading(
337
350
public inline fun <T > ApiResult<T?>?.requireNotNull (): ApiResult <T & Any > = errorOnNull()
338
351
339
352
/* *
340
- * Throws if [this] is not [Success] and returns [Success] otherwise.
353
+ * Alias for [orThrow]
341
354
* @see orThrow
342
355
*/
343
- public inline fun <T > ApiResult<T>.require (): ApiResult < T > = Success ( ! this )
356
+ public inline fun <T > ApiResult<T>.require (): T = orThrow( )
344
357
345
358
/* *
346
359
* Change the type of the [Success] to [R] without affecting [Error]/[Loading] results
@@ -352,25 +365,19 @@ public inline infix fun <T, R> ApiResult<T>.map(block: (T) -> R): ApiResult<R> {
352
365
contract {
353
366
callsInPlace(block, InvocationKind .AT_MOST_ONCE )
354
367
}
355
- return fold(
356
- onSuccess = { Success (value = block(it)) },
357
- onError = { Error (value = it) },
358
- onLoading = { ApiResult .Loading () }
359
- )
368
+ if (isSuccess) return Success (value = block(value as T ))
369
+ return this as ApiResult <R >
360
370
}
361
371
362
372
/* *
363
373
* Map the [Success] result using [transform], and if the result is not a success, return [default]
364
374
*/
365
- public inline fun <T , R > ApiResult<T>.mapOrDefault (default : () -> R , transform : (T ) -> R ): R {
375
+ public inline fun <T , R > ApiResult<T>.mapOrDefault (default : (e: Exception ) -> R , transform : (T ) -> R ): R {
366
376
contract {
367
377
callsInPlace(transform, InvocationKind .AT_MOST_ONCE )
368
378
callsInPlace(default, InvocationKind .AT_MOST_ONCE )
369
379
}
370
- return fold(
371
- onSuccess = { transform(it) },
372
- onError = { default() }
373
- )
380
+ return map(transform).orElse(default)
374
381
}
375
382
376
383
/* *
@@ -379,10 +386,7 @@ public inline fun <T, R> ApiResult<T>.mapOrDefault(default: () -> R, transform:
379
386
public inline fun <T , R > ApiResult<T>.mapEither (
380
387
success : (T ) -> R ,
381
388
error : (Exception ) -> Exception ,
382
- ): ApiResult <R > = fold(
383
- onSuccess = { Success (success(it)) },
384
- onError = { Error (value = error(it)) }
385
- )
389
+ ): ApiResult <R > = map(success).mapError(error)
386
390
387
391
/* *
388
392
* Maps [Loading] to a [Success], not affecting other states.
@@ -414,7 +418,7 @@ public inline infix fun <reified R : Exception, T> ApiResult<T>.mapError(block:
414
418
callsInPlace(block, InvocationKind .AT_MOST_ONCE )
415
419
}
416
420
return when {
417
- value is Error && value.e is R -> Error (value = block(value.e))
421
+ value is Error && value.e is R -> Error (e = block(value.e))
418
422
else -> this
419
423
}
420
424
}
@@ -427,11 +431,10 @@ public inline fun <T> ApiResult<T>.mapErrorToCause(): ApiResult<T> = mapError {
427
431
/* *
428
432
* Unwrap an ApiResult<ApiResult<T>> to be ApiResult<T>
429
433
*/
430
- public inline fun <T > ApiResult<ApiResult<T>>.unwrap (): ApiResult <T > = fold(
431
- onSuccess = { it },
432
- onError = { Error (value = it) },
433
- onLoading = { ApiResult .Loading () },
434
- )
434
+ public inline fun <T > ApiResult<ApiResult<T>>.unwrap (): ApiResult <T > = when (value) {
435
+ is Error , is Loading -> this
436
+ else -> value
437
+ } as ApiResult <T >
435
438
436
439
/* *
437
440
* Change the type of successful result to [R], also wrapping [block]
@@ -450,17 +453,17 @@ public inline infix fun <T, R> ApiResult<T>.tryMap(
450
453
* @see errorIf
451
454
* @see errorIfEmpty
452
455
*/
453
- public inline fun <T > ApiResult<T?>?.errorOnNull (
456
+ public inline fun <T : Any > ApiResult<T?>?.errorOnNull (
454
457
exception : () -> Exception = { ConditionNotSatisfiedException ("Value was null") },
455
- ): ApiResult <T & Any > {
458
+ ): ApiResult <T > {
456
459
contract {
457
- returns() implies ( this @errorOnNull != null )
460
+ returnsNotNull( )
458
461
}
459
- return when (this ?.value) {
460
- is Error -> Error (value = value .e)
462
+ return when (val r = this ?.value) {
463
+ is Error -> Error (e = r .e)
461
464
is Loading -> ApiResult .Loading ()
462
- null -> Error (value = exception())
463
- else -> ApiResult (value = value )
465
+ null -> Error (e = exception())
466
+ else -> Success (value = r as T )
464
467
}
465
468
}
466
469
@@ -531,10 +534,8 @@ public inline fun <T> ApiResult<T>.recoverIf(
531
534
callsInPlace(condition, InvocationKind .AT_MOST_ONCE )
532
535
callsInPlace(block, InvocationKind .AT_MOST_ONCE )
533
536
}
534
- return when {
535
- value is Error && condition(value.e) -> block(value.e)
536
- else -> ApiResult (value = value)
537
- }
537
+ if (value !is Error || ! condition(value.e)) return this
538
+ return block(value.e)
538
539
}
539
540
540
541
/* *
0 commit comments