Skip to content

Commit

Permalink
Add mapOptionalOnce
Browse files Browse the repository at this point in the history
  • Loading branch information
hpost committed Jan 13, 2020
1 parent eb62183 commit b98bf4e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ state().mapOptional { bar }
```


### Observable.mapOptionalOnce
Map to one nullable property of the state, wrap in `Optional`, and ensure
that only first value is observed

```kotlin
state().mapOptionalOnce { bar }
.subscribe { println(it) }

// --> None
```


### Observable.mapOptionalDistinct
Map to one nullable property of the state and wrap in `Optional`
and ensure that subsequently emitted values are distinct
Expand Down Expand Up @@ -131,7 +143,7 @@ state().mapSomeOnce { bar }
## Binaries
```gradle
dependencies {
implementation "cc.femto:rx-mapping-extensions:0.3"
implementation "cc.femto:rx-mapping-extensions:0.4"
}
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ plugins {
}

group 'com.github.hpost'
version '0.3'
version '0.4'

repositories {
mavenCentral()
Expand Down
14 changes: 14 additions & 0 deletions src/main/kotlin/cc/femto/rx/extensions/Mapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ inline fun <T, R : Any> Observable<T>.mapOnce(crossinline mapper: T.() -> R): Ob
inline fun <T, R : Any> Observable<T>.mapOptional(crossinline mapper: T.() -> R?): Observable<Optional<R>> =
this.map { mapper(it).toOptional() }

/**
* Map the stream to the value returned from [mapper], which is wrapped in an [Optional],
* and then apply [Observable.take] with value `1` to ensure the stream will
* complete after emitting one value
*
* Usage:
* <code>
* stream.mapOptionalOnce { foo }
* .subscribe { /* access at most one value wrapped in Optional */ }
* </code>
*/
inline fun <T, R : Any> Observable<T>.mapOptionalOnce(crossinline mapper: T.() -> R?): Observable<Optional<R>> =
this.mapOptional(mapper).take(1)

/**
* Applies [mapOptional] and then [Observable.distinctUntilChanged] to ensure
* the stream won't emit if the value in [mapper] has not changed
Expand Down
19 changes: 19 additions & 0 deletions src/test/kotlin/cc/femto/rx/extensions/MappingSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,25 @@ class MappingSpec : Spek({
}
}

describe("mapOptionalOnce") {
lateinit var observer: TestObserver<Optional<String>>

beforeEachTest {
state = Observable.just(
State(bar = "initialized"),
State(bar = null),
State(bar = "changed")
)
observer = state.mapOptionalOnce { bar }.test()
}

it("maps to nullable property, wraps in `Optional`, and completes after one emission") {
observer.assertValues(
Some("initialized")
)
}
}

describe("mapOptionalDistinct") {
lateinit var observer: TestObserver<Optional<String>>

Expand Down

0 comments on commit b98bf4e

Please sign in to comment.