-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8d064c5
commit 742c355
Showing
6 changed files
with
291 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# AndroidCommons | ||
|
||
Android library with common utilities required when building Android apps. | ||
|
||
--- | ||
|
||
## Usage | ||
|
||
Step 1: Add JitPack in your **root build.gradle** : | ||
|
||
```groovy | ||
allprojects { | ||
repositories { | ||
... | ||
maven { url 'https://jitpack.io' } | ||
} | ||
} | ||
``` | ||
|
||
Step 2: Add AndroidCommons dependency to your **app build.gradle**: | ||
|
||
```groovy | ||
dependencies { | ||
implementation 'com.github.The-Streamliners:AndroidCommons:0.1.0' | ||
} | ||
``` | ||
|
||
--- | ||
|
||
## Utilities | ||
|
||
### TasksInParallelHelper | ||
|
||
TasksInParallelHelper is a helper class that performs task in parallel. Any input type (I) & output type (O) is supported. By Implementing task class, you can perform any task on I to generate O, whether it be a long IO operation or a network call. | ||
|
||
[View examples](docs/TasksInParallelHelper.md) | ||
|
||
--- | ||
|
||
### ResultOf<T> | ||
|
||
ResultOf is a resource wrapper class. While performing an IO / Network operation, there are 2 possibilities: | ||
|
||
- Task will be successful & we will get some data T | ||
|
||
- Task may fail producing some exception | ||
|
||
|
||
ResultOf<T> class makes it easier to wrap these 2 possibilities in one. | ||
|
||
[View examples & features](docs/ResultOf.md) |
37 changes: 37 additions & 0 deletions
37
commons/src/main/java/com/streamliners/commons/ResultOf.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.streamliners.commons | ||
|
||
sealed class ResultOf<T>(val data: T? = null, val message: String? = null) { | ||
|
||
class Success<T>(data: T) : ResultOf<T>(data) | ||
|
||
class Error<T>(message: String) : ResultOf<T>(message = message) | ||
|
||
fun onSuccess(handler: (T) -> Unit): ResultOf<T> { | ||
if(this is Success) | ||
data?.let(handler) | ||
return this | ||
} | ||
|
||
fun onFailure(handler: (String) -> Unit): ResultOf<T> { | ||
if(this is Error) | ||
message?.let(handler) | ||
return this | ||
} | ||
|
||
fun finally(handler: () -> Unit): ResultOf<T> { | ||
handler() | ||
return this | ||
} | ||
|
||
fun await(): T { | ||
if(this is Success) | ||
data?.let { | ||
return it | ||
} ?: throw Exception("Something went wrong") | ||
else | ||
message?.let { | ||
throw Exception(it) | ||
} ?: throw Exception("Something went wrong") | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# ResultOf<T> | ||
|
||
ResultOf is a resource wrapper class. While performing an IO / Network operation, there are 2 possibilities: | ||
|
||
- Task will be successful & we will get some data T | ||
|
||
- Task may fail producing some exception | ||
|
||
|
||
ResultOf class makes it easier to wrap these 2 possibilities in one. | ||
|
||
--- | ||
|
||
## Code without ResultOf class | ||
|
||
You'll have to use try catch whenever calling a suspending function | ||
|
||
```kotlin | ||
try { | ||
val user = userRepository.getUser() | ||
} catch(e: Exception) { | ||
// Handle error | ||
} | ||
|
||
|
||
OR | ||
|
||
|
||
coroutineScope.launch(exceptionHandler) { | ||
val user = userRepository.getUser() | ||
} | ||
``` | ||
|
||
## Using ResultOf class with when block | ||
|
||
```kotlin | ||
when( | ||
val result = userRepository.getUser() | ||
) { | ||
is Success -> { | ||
val user = result.data | ||
// Consume result | ||
} | ||
is Error -> { | ||
val error = result.message | ||
// Show error | ||
} | ||
} | ||
``` | ||
|
||
The code might look longer, but there are 2 functions at rescue : | ||
|
||
## Using ResultOf with onSuccess & onFailure | ||
|
||
```kotlin | ||
userRepository.getUser() | ||
.onSuccess { user -> | ||
|
||
}.onFailure { error -> | ||
|
||
} | ||
``` | ||
|
||
But these functions lead to callback hell when calling multiple suspending functions in a sequence: | ||
|
||
## Callback hell | ||
|
||
```kotlin | ||
userRepository.getUser() | ||
.onSuccess { user -> | ||
paymentsRepository.getPayments(user) | ||
.onSuccess { payments -> | ||
|
||
}.onFailure { error -> | ||
|
||
} | ||
}.onFailure { error -> | ||
|
||
} | ||
``` | ||
|
||
Is there a way out? Of course, ResultOf class offers await() method : | ||
|
||
## Using ResultOf class with await() | ||
|
||
```kotlin | ||
try { | ||
val user = userRepository.getUser().await() | ||
val payments = paymentsRepository.getPayments(user).await() | ||
} catch(e: Exception) { | ||
// Handle error | ||
} | ||
|
||
OR | ||
|
||
coroutineScope.launch(exceptionHandler) { | ||
val user = userRepository.getUser().await() | ||
val payments = paymentsRepository.getPayments(user).await() | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# TasksInParallelHelper | ||
|
||
TasksInParallelHelper is a helper class that performs task in parallel. Any input type (I) & output type (O) is supported. By Implementing task class, you can perform any task on I to generate O, whether it be a long IO operation or a network call. | ||
|
||
--- | ||
|
||
## Kotlin example | ||
|
||
Step 1: Prepare a list of inputs of any input type A | ||
|
||
```kotlin | ||
val inputs = listOf(A(1), A(2), A(3)) | ||
``` | ||
|
||
Step 2: Implement Task class to transform input type A into output type B | ||
|
||
```kotlin | ||
val task: Task<A, B> = | ||
object : Task<A, B>() { | ||
override fun perform(input: A, listener: Listener<B>) { | ||
// Simple stupid task that converts int to String | ||
val output = B(input.x.toString()) | ||
listener.onSuccess(output) | ||
} | ||
} | ||
``` | ||
|
||
Step 3: Implement listener to get outputs of output type B | ||
|
||
```kotlin | ||
val listener: TasksListener<B> = | ||
object : TasksListener<B> { | ||
override fun onSuccess(outputs: List<B>) { | ||
// Do something with the outputs | ||
} | ||
|
||
override fun onFailure(error: String) { | ||
// Show the error! | ||
} | ||
} | ||
``` | ||
|
||
Step 4: Finally perform the tasks in parallel! | ||
|
||
```kotlin | ||
TasksInParallelHelper<A, B>() | ||
.doTasksInParallel(inputs, task, listener) | ||
``` | ||
|
||
--- | ||
|
||
## Java Example | ||
|
||
Step 1: Prepare a list of inputs of any input type A | ||
|
||
```kotlin | ||
List<A> inputs = Arrays.asList(new A(1), new A(2), new A(3)); | ||
``` | ||
|
||
Step 2: Implement Task class to transform input type A into output type B | ||
|
||
```kotlin | ||
Task<A, B> task = | ||
new Task<A, B>() { | ||
@Override | ||
public void perform(A input, @NonNull Listener<B> listener) { | ||
// Simple stupid task that converts int to String | ||
B output = new B(String.valueOf(input.getX())); | ||
listener.onSuccess(output); | ||
} | ||
}; | ||
``` | ||
|
||
Step 3: Implement listener to get outputs of output type B | ||
|
||
```kotlin | ||
TasksInParallelHelper.TasksListener<B> listener = | ||
new TasksInParallelHelper.TasksListener<B>() { | ||
@Override | ||
public void onSuccess(@NonNull List<? extends B> outputs) { | ||
// Do something with the outputs | ||
} | ||
|
||
@Override | ||
public void onFailure(@NonNull String error) { | ||
// Show the error! | ||
} | ||
}; | ||
``` | ||
|
||
Step 4: Finally perform the tasks in parallel! | ||
|
||
```kotlin | ||
new TasksInParallelHelper<A, B>() | ||
.doTasksInParallel(inputs, task, listener); | ||
``` |