Skip to content

Commit 2583e6c

Browse files
authored
Version 0.12.0 (#42)
- [kotlinx.coroutines 0.24.0](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.24.0) - Compiled against Kotlin 1.2.60 - Reformat code with official Kotlin style guide - Gradle 4.9 - Bintray plugin 1.8.4
1 parent a219173 commit 2583e6c

File tree

11 files changed

+164
-65
lines changed

11 files changed

+164
-65
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# CHANGELOG
22

3+
## Version 0.12.0 (2017-08-04)
4+
5+
- [kotlinx.coroutines 0.24.0](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.24.0)
6+
- Compiled against Kotlin 1.2.60
7+
38
## Version 0.11.0 (2017-06-12)
49

5-
- [kotlinx.coroutines 0.23.1](https://github.com/Kotlin/kotlinx.coroutines/releases/)
10+
- [kotlinx.coroutines 0.23.1](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/0.23.1)
611
- Compiled against Kotlin 1.2.41
712

813
Thanks to [Thomas Schmidt](https://github.com/bohsen) for contribution

README.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,28 @@
66

77
This is a small library that provides the [Kotlin Coroutines](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md) [suspending](https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#suspending-functions) extension `Call.await()` for [Retrofit 2](https://github.com/square/retrofit)
88

9-
Based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation
9+
Based on [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) implementation.
10+
11+
This branch uses Kotlin experimental package `kotlin.coroutines.experimental` (pre-1.3).
12+
13+
Migration to package stable `kotlin.coroutines` package is planned and work in progress.
1014

1115
## Download
1216
Download the [JAR](https://bintray.com/gildor/maven/kotlin-coroutines-retrofit#files/ru/gildor/coroutines/kotlin-coroutines-retrofit):
1317

1418
Gradle:
1519

1620
```groovy
17-
compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.11.0'
21+
compile 'ru.gildor.coroutines:kotlin-coroutines-retrofit:0.12.0'
1822
```
1923

20-
Maven:
24+
Maven:getOrThrow
2125

2226
```xml
2327
<dependency>
2428
<groupId>ru.gildor.coroutines</groupId>
2529
<artifactId>kotlin-coroutines-retrofit</artifactId>
26-
<version>0.11.0</version>
30+
<version>0.12.0</version>
2731
</dependency>
2832
```
2933

@@ -49,7 +53,7 @@ In case of an HTTP error or an invocation exception `await()` throws an exceptio
4953

5054
```kotlin
5155
// You can use retrofit suspended extension inside any coroutine block
52-
fun main(args: Array<String>) = runBlocking {
56+
fun main(args: Array<String>): Unit = runBlocking {
5357
try {
5458
// Wait (suspend) for result
5559
val user: User = api.getUser("username").await()
@@ -76,7 +80,7 @@ In case of an invocation exception `awaitResponse()` throws an exception
7680

7781
```kotlin
7882
// You can use retrofit suspended extension inside any coroutine block
79-
fun main(args: Array<String>) = runBlocking {
83+
fun main(args: Array<String>): Unit = runBlocking {
8084
try {
8185
// Wait (suspend) for response
8286
val response: Response<User> = api.getUser("username").awaitResponse()
@@ -100,7 +104,7 @@ fun Call<T>.awaitResult(): Result<T>
100104
```
101105

102106
```kotlin
103-
fun main(args: Array<String>) = runBlocking {
107+
fun main(args: Array<String>): Unit = runBlocking {
104108
// Wait (suspend) for Result
105109
val result: Result<User> = api.getUser("username").awaitResult()
106110
// Check result type
@@ -118,7 +122,7 @@ fun main(args: Array<String>) = runBlocking {
118122
Also, `Result` has a few handy extension functions that allow to avoid `when` block matching:
119123

120124
```kotlin
121-
fun main(args: Array<String>) = runBlocking {
125+
fun main(args: Array<String>): Unit = runBlocking {
122126
val result: User = api.getUser("username").awaitResult()
123127

124128
//Return value for success or null for any http error or exception
@@ -138,7 +142,7 @@ All `Result` classes also implemented one or both interfaces: `ResponseResult` a
138142
You can use them for access to shared properties of different classes from `Result`
139143

140144
```kotlin
141-
fun main(args: Array<String>) = runBlocking {
145+
fun main(args: Array<String>): Unit = runBlocking {
142146
val result: User = api.getUser("username").awaitResult()
143147

144148
//Result.Ok and Result.Error both implement ResponseResult
@@ -162,7 +166,7 @@ extensions `.await()` and `.awaitResult()` are available only for
162166
non-nullable `Call<Body>` or platform `Call<Body!>` body types:
163167

164168
```kotlin
165-
fun main(args: Array<String>) = runBlocking {
169+
fun main(args: Array<String>): Unit = runBlocking {
166170
val user: Call<User> = api.getUser("username")
167171
val userOrNull: Call<User?> = api.getUserOrNull("username")
168172

@@ -194,7 +198,7 @@ You can do that by wrapping calls with `kotlinx.coroutines` [async()](https://ko
194198

195199

196200
```kotlin
197-
fun main(args: Array<String>) = runBlocking {
201+
fun main(args: Array<String>): Unit = runBlocking {
198202
val users = listOf("user1", "user2", "user3")
199203
.map { username ->
200204
// Pass any coroutine context that fits better for your case

build.gradle.kts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin
1212
import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper
1313

1414
plugins {
15-
id("org.jetbrains.kotlin.jvm") version "1.2.41"
16-
id("com.jfrog.bintray") version "1.7.3"
15+
id("org.jetbrains.kotlin.jvm") version "1.2.60"
16+
id("com.jfrog.bintray") version "1.8.4"
1717
jacoco
1818
`maven-publish`
1919
id("org.jetbrains.dokka") version "0.9.16"
2020
}
2121

2222
group = "ru.gildor.coroutines"
23-
version = "0.11.0"
23+
version = "0.12.0"
2424
description = "Provides Kotlin Coroutines suspendable await() extensions for Retrofit Call"
2525

2626
repositories {
@@ -34,7 +34,7 @@ java {
3434

3535
dependencies {
3636
compile("org.jetbrains.kotlin:kotlin-stdlib")
37-
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.23.1")
37+
compile("org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0")
3838
compile("com.squareup.retrofit2:retrofit:2.4.0")
3939
testCompile("junit:junit:4.12")
4040
}

gradle/wrapper/gradle-wrapper.jar

-295 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
# suppress inspection "UnusedProperty" for whole file
12
distributionBase=GRADLE_USER_HOME
23
distributionPath=wrapper/dists
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
35
zipStoreBase=GRADLE_USER_HOME
46
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip

src/main/kotlin/ru/gildor/coroutines/retrofit/CallAwait.kt

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2018 Andrey Mischenko
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package ru.gildor.coroutines.retrofit
218

319
import kotlinx.coroutines.experimental.CancellableContinuation
@@ -8,7 +24,7 @@ import retrofit2.HttpException
824
import retrofit2.Response
925

1026
/**
11-
* Suspend extension that allows suspend [Call] inside coroutine.
27+
* Suspend extension that allows suspend [Call] inside of a coroutine.
1228
*
1329
* @return Result of request or throw exception
1430
*/
@@ -20,7 +36,7 @@ public suspend fun <T : Any> Call<T>.await(): T {
2036
val body = response.body()
2137
if (body == null) {
2238
continuation.resumeWithException(
23-
NullPointerException("Response body is null: $response")
39+
NullPointerException("Response body is null: $response")
2440
)
2541
} else {
2642
continuation.resume(body)
@@ -68,23 +84,24 @@ public suspend fun <T : Any?> Call<T>.awaitResponse(): Response<T> {
6884
* Suspend extension that allows suspend [Call] inside coroutine.
6985
*
7086
* @return sealed class [Result] object that can be
71-
* casted to [Result.Ok] (success) or [Result.Error] (HTTP error) and [Result.Exception] (other errors)
87+
* casted to [Result.Ok] (success) or [Result.Error] (HTTP error)
88+
* and [Result.Exception] (other errors)
7289
*/
7390
public suspend fun <T : Any> Call<T>.awaitResult(): Result<T> {
7491
return suspendCancellableCoroutine { continuation ->
7592
enqueue(object : Callback<T> {
7693
override fun onResponse(call: Call<T>?, response: Response<T>) {
7794
continuation.resume(
78-
if (response.isSuccessful) {
79-
val body = response.body()
80-
if (body == null) {
81-
Result.Exception(NullPointerException("Response body is null"))
82-
} else {
83-
Result.Ok(body, response.raw())
84-
}
95+
if (response.isSuccessful) {
96+
val body = response.body()
97+
if (body == null) {
98+
Result.Exception(NullPointerException("Response body is null"))
8599
} else {
86-
Result.Error(HttpException(response), response.raw())
100+
Result.Ok(body, response.raw())
87101
}
102+
} else {
103+
Result.Error(HttpException(response), response.raw())
104+
}
88105
)
89106
}
90107

src/main/kotlin/ru/gildor/coroutines/retrofit/Result.kt

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2018 Andrey Mischenko
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package ru.gildor.coroutines.retrofit
218

319
import okhttp3.Response
@@ -12,8 +28,8 @@ public sealed class Result<out T : Any> {
1228
* Successful result of request without errors
1329
*/
1430
public class Ok<out T : Any>(
15-
public val value: T,
16-
override val response: Response
31+
public val value: T,
32+
override val response: Response
1733
) : Result<T>(), ResponseResult {
1834
override fun toString() = "Result.Ok{value=$value, response=$response}"
1935
}
@@ -22,8 +38,8 @@ public sealed class Result<out T : Any> {
2238
* HTTP error
2339
*/
2440
public class Error(
25-
override val exception: HttpException,
26-
override val response: Response
41+
override val exception: HttpException,
42+
override val response: Response
2743
) : Result<Nothing>(), ErrorResult, ResponseResult {
2844
override fun toString() = "Result.Error{exception=$exception}"
2945
}
@@ -33,7 +49,7 @@ public sealed class Result<out T : Any> {
3349
* exception occurred creating the request or processing the response
3450
*/
3551
public class Exception(
36-
override val exception: Throwable
52+
override val exception: Throwable
3753
) : Result<Nothing>(), ErrorResult {
3854
override fun toString() = "Result.Exception{$exception}"
3955
}
@@ -57,14 +73,12 @@ public interface ErrorResult {
5773
/**
5874
* Returns [Result.Ok.value] or `null`
5975
*/
60-
public fun <T : Any> Result<T>.getOrNull(): T? =
61-
if (this is Result.Ok) this.value else null
76+
public fun <T : Any> Result<T>.getOrNull(): T? = (this as? Result.Ok)?.value
6277

6378
/**
6479
* Returns [Result.Ok.value] or [default]
6580
*/
66-
public fun <T : Any> Result<T>.getOrDefault(default: T): T =
67-
getOrNull() ?: default
81+
public fun <T : Any> Result<T>.getOrDefault(default: T): T = getOrNull() ?: default
6882

6983
/**
7084
* Returns [Result.Ok.value] or throw [throwable] or [ErrorResult.exception]

src/test/kotlin/ru/gildor/coroutines/retrofit/CallAwaitTest.kt

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1+
/*
2+
* Copyright 2018 Andrey Mischenko
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package ru.gildor.coroutines.retrofit
218

319
import kotlinx.coroutines.experimental.CoroutineScope
420
import kotlinx.coroutines.experimental.Unconfined
521
import kotlinx.coroutines.experimental.async
622
import kotlinx.coroutines.experimental.runBlocking
7-
import org.junit.Assert.*
23+
import org.junit.Assert.assertEquals
24+
import org.junit.Assert.assertFalse
25+
import org.junit.Assert.assertNull
26+
import org.junit.Assert.assertSame
27+
import org.junit.Assert.assertTrue
28+
import org.junit.Assert.fail
829
import org.junit.Test
930
import retrofit2.Call
1031
import retrofit2.HttpException
@@ -232,12 +253,12 @@ class CallAwaitTest {
232253
}
233254

234255
private fun <T> checkRequestCancelWithException(
235-
block: suspend (Call<String>) -> T
256+
block: suspend (Call<String>) -> T
236257
) = testBlocking {
237258
val request = MockedCall(
238-
ok = DONE,
239-
autoStart = false,
240-
cancelException = IllegalStateException()
259+
ok = DONE,
260+
autoStart = false,
261+
cancelException = IllegalStateException()
241262
)
242263
val async = async(coroutineContext, block = { block(request) })
243264
//We shouldn't crash on cancel exception
@@ -252,8 +273,8 @@ class CallAwaitTest {
252273

253274
private fun <T> checkJobCancelWithException(block: suspend (Call<String>) -> T) = testBlocking {
254275
val request = MockedCall<String>(
255-
exception = IllegalArgumentException(),
256-
autoStart = false
276+
exception = IllegalArgumentException(),
277+
autoStart = false
257278
)
258279
val result = async(coroutineContext) {
259280
block(request)
@@ -264,7 +285,7 @@ class CallAwaitTest {
264285
}
265286

266287
private fun <T> checkJobCancel(
267-
block: suspend (Call<String>) -> T
288+
block: suspend (Call<String>) -> T
268289
) = testBlocking {
269290
val request = MockedCall(DONE, autoStart = false)
270291
val async = async(coroutineContext) { block(request) }
@@ -277,3 +298,4 @@ class CallAwaitTest {
277298
private fun testBlocking(block: suspend CoroutineScope.() -> Unit) {
278299
runBlocking(Unconfined, block)
279300
}
301+

0 commit comments

Comments
 (0)