Skip to content

Commit

Permalink
Improve README
Browse files Browse the repository at this point in the history
  • Loading branch information
skydoves committed Oct 15, 2024
1 parent 07e9852 commit bd78f80
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 30 deletions.
78 changes: 54 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,53 @@
## Download
[![Maven Central](https://img.shields.io/maven-central/v/com.github.skydoves/whatif.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.skydoves%22%20AND%20a:%22whatif%22)

☔ WhatIf has been downloaded in more than __110k__ Kotlin and Android projects all over the world! <br><br>
☔ WhatIf has been downloaded in more than __300k__ Kotlin and Android projects all over the world! <br><br>
![downloads](https://user-images.githubusercontent.com/24237865/101273131-2187a980-37d6-11eb-9000-e1cd10f87b0d.png)

### Gradle
Add the dependency below to your module's `build.gradle` file:

```gradle
dependencies {
implementation "com.github.skydoves:whatif:1.1.4"
implementation("com.github.skydoves:whatif:1.1.4")
}
```

## Usage

### WhatIf
`WhatIf` is an expression for invoking `whatIf` lambda when the given boolean is true and not-null.

`WhatIf` is a Kotlin expression that triggers a lambda expression (`whatIf` block) when the provided boolean condition is true and the object is non-null. It's a concise way to handle conditional logic without needing verbose if-else statements, enabling cleaner, more readable code for specific actions when conditions are met.

```kotlin
val nullableBoolean: Boolean? = true
whatIf(nullableBoolean) {
log("not-null and true : $nullableBoolean")
}
```

Here is an extension for nullable booleans.

```kotlin
nullableBoolean.whatIf {
log("not-null and true : $nullableBoolean")
}
```

### WhatIfNot
The `whatIf` expression is basically composed with `given`, `whatIf`, `whatIfNot`.<br>
If the target is null or false, `whatIfNot` will be invoked instead of the `whatIf`.<br>
If we do not need to handle `whatIfNot` case, it can be omitted.

The `whatIf` expression consists of three main parts: `given`, `whatIf`, and `whatIfNot`. If the condition is true and the target is non-null, the `whatIf` lambda is executed. However, if the condition is false or the target is null, the `whatIfNot` lambda will be invoked instead. The `whatIfNot` block is optional, so if there's no need to handle the false/null case, it can simply be omitted, allowing for more concise code when necessary.

```kotlin
whatIf(
given = nullableBoolean,
whatIf = { log("not-null and true : $nullableBoolean") },
whatIfNot = { log("null or false : $nullableBoolean") }
)
```
Or here is an extension for nullable boolean.

Here's an extension function designed specifically for nullable booleans.

```kotlin
nullableBoolean.whatIf(
whatIf = { log("not-null and true : $nullableBoolean") },
Expand All @@ -65,9 +74,9 @@ nullableBoolean.whatIf(
```

### WhatIf in the builder pattern
Sometimes we should set builder differently to depend on options.<br>
`WhatIf` is useful when using a chaining function like a builder pattern.<br>
It can be applied to any builder patterns like `AlertDialog.Builder` or anything.

Sometimes, you need to configure a builder differently depending on the available options. This is where `WhatIf` proves useful, especially when using a chaining function like in builder patterns. It can be seamlessly applied to various builder patterns, such as `AlertDialog.Builder` or any other similar construct, allowing conditional logic to be injected cleanly and fluently based on the provided conditions, without breaking the flow of method chaining.

```kotlin
val balloon = Balloon.Builder(baseContext)
.setArrowSize(10)
Expand All @@ -79,15 +88,18 @@ val balloon = Balloon.Builder(baseContext)
```

### WhatIfNotNull
`WhatIfNotNull` is an expression for invoking `whatIf` lambda when the target object is not null.

`WhatIfNotNull` is a Kotlin expression that triggers the `whatIf` lambda when the target object is not null. This function simplifies handling nullable objects, allowing you to perform actions only when the object is valid, making your code cleaner by avoiding manual null checks. It's particularly useful for eliminating boilerplate when working with nullable types in Kotlin.

```kotlin
val nullableObject: Person? = Person()
nullableObject.whatIfNotNull {
log("$it is not null")
}
```
And we can handle the null case.<br>
If the target is null, `whatIfNot` will be invoked instead of the `whatIf`.

You can also handle cases where the target object is null. In such scenarios, instead of executing the `whatIf` lambda, the `whatIfNot` lambda will be triggered. This ensures that null cases are properly managed, providing an alternative action when the object is null, making your code more robust and adaptable to nullable conditions.

```kotlin
nullableObject.whatIfNotNull(
whatIf = { log("$it is not null.") },
Expand All @@ -96,6 +108,7 @@ nullableObject.whatIfNotNull(
```

### WhatIfNotNullAs

`WhatIfNotNullAs` is an expression for invoking `whatIf` lambda when the target object is not null and the target can be cast by the desired type, the receiver will get a casted type.

```diff
Expand All @@ -107,7 +120,8 @@ nullableObject.whatIfNotNull(
+ log(poster.name)
+ }
```
And we can also handle the exception case (target is null or can't cast by the desired type) using `whatIfNot`.

You can also handle the exception case (target is null or can't cast by the desired type) using `whatIfNot`.

```diff
- (serializable as? Poster?)?.let { poster ->
Expand All @@ -124,29 +138,35 @@ And we can also handle the exception case (target is null or can't cast by the d
```

### WhatIfNotNullOrEmpty
An expression for invoking `whatIf` lambda when the __string__, __collections__ and __array type__ is not null and not empty.<br>
If the collections or array type target is null or empty, `whatIfNot` will be invoked instead of the `whatIf`.

An expression for invoking the `whatIf` lambda when the target, such as a **string**, **collection**, or **array**, is neither null nor empty. If the target is null or empty, the `whatIfNot` lambda will be executed instead. This approach ensures that you can easily handle non-empty, valid collections or arrays, while providing an alternative behavior for null or empty cases, streamlining conditional logic when dealing with these data types.

```kotlin
val nullableString: String? = "NotNullOrEmpty"
nullableString.whatIfNotNullOrEmpty {
log("$it is not null and not empty")
}
```

Here is an example for collections.

```kotlin
nullableList.whatIfNotNullOrEmpty {
log("list $it is not null and not empty")
}
```
And we can handle the null or empty case.

You can also handle the null or empty case.

```kotlin
nullableList.whatIfNotNullOrEmpty(
whatIf = { log("list $it is not null and not empty") },
whatIfNot = { log("list is null or empty") }
)
```

Here is the same example for the array.

```kotlin
nullableArray.whatIfNotNullOrEmpty {
log("$it is not null and not empty")
Expand All @@ -156,7 +176,9 @@ nullableArray.whatIfNotNullOrEmpty {
Array, ByteArray, ShortArray, IntArray, LongArray, FloatArray, DoubleArray, BooleanArray, CharArray

#### Collections
We can use some expressions for List, Map, and Set.

You can use some expressions for List, Map, and Set.

- whatIfNotNullOrEmpty: An expression for invoking `whatIf` when the `List` is not null and not empty.
- addWhatIfNotNull: An expression for adding an element and invoking `whatIf` when the element is not null.
- addAllWhatIfNotNull: An expression for adding an element and invoking `whatIf` when the element is not null.
Expand All @@ -165,7 +187,9 @@ We can use some expressions for List, Map, and Set.


### WhatIfMap

The basic concept is the same as `whatIf`. An expression for invoking `whatIf` when the target object is not null. It is useful when the type of the receiver and the result should be different.<br>

```kotlin
val length: Int = nullableString.whatIfMap(
whatIf = { it.length },
Expand All @@ -175,7 +199,9 @@ val length: Int = nullableString.whatIfMap(
}
)
```
We can use a default value instead of the `whatIfNot` and it can be omitted.

You can use a default value instead of the `whatIfNot` and it can be omitted.

```kotlin
val length = nullableString.whatIfMap(
default = -1
Expand Down Expand Up @@ -206,11 +232,15 @@ nullableBoolean.whatIfOr(predicate) {
```

## WhatIf for Android Extension
We can use the whatIf extensions related to the Android project.<br>

You can use the whatIf extensions related to the Android project.<br>

[![Maven Central](https://img.shields.io/maven-central/v/com.github.skydoves/whatif-android.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.github.skydoves%22%20AND%20a:%22whatif-android%22)

### Gradle
Add a dependency code to your **module**'s `build.gradle` file.

Add the dependency below to your **module**'s `build.gradle` file:

```gradle
dependencies {
implementation "com.github.skydoves:whatif-android:version"
Expand All @@ -226,14 +256,14 @@ this@MainActivity.whatIfHasExtras {
foo = "${it.getString("foo")}"
}
```
And we can handle the null case.<br>
You can also handle the null case.<br>
```kotlin
this@MainActivity.whatIfHasExtras(
whatIf = { foo = "${it.getString("foo")}" },
whatIfNot = { log("intent extras is null or empty.") }
)
```
We can null-check and typecast simultaneously when we getting intent extra data.
You can null-check and typecast simultaneously when you getting intent extra data.
```kotlin
whatIfHasSerializableExtra<Poster>("poster") { poster ->
...
Expand Down Expand Up @@ -288,7 +318,7 @@ class MainActivity : AppCompatActivity(), OnClickCallback {
}
```

We can get the parent Activity's `OnClickCallback` interface on Fragment as following with the `whatIfFindParentInterface`:
You can get the parent Activity's `OnClickCallback` interface on Fragment as following with the `whatIfFindParentInterface`:
```kotlin
class MainFragment: Fragment() {

Expand Down
10 changes: 4 additions & 6 deletions whatif/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,6 @@ kotlin {
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
languageSettings.optIn("com.skydoves.sandwich.annotations.InternalSandwichApi")
}

val commonTest by getting {
dependencies {
implementation(libs.junit)
}
}
}

explicitApi()
Expand All @@ -80,4 +74,8 @@ android {
tasks.withType(JavaCompile::class.java).configureEach {
this.targetCompatibility = libs.versions.jvmTarget.get()
this.sourceCompatibility = libs.versions.jvmTarget.get()
}

dependencies {
androidTestImplementation(libs.junit)
}

0 comments on commit bd78f80

Please sign in to comment.