Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.x: Add materialize() and dematerialize() #6278

Merged
merged 4 commits into from
Nov 6, 2018

Conversation

akarnokd
Copy link
Member

@akarnokd akarnokd commented Nov 1, 2018

This PR adds the materialize operator to Maybe, Single and Completable to turn their signals into the corresponding Notification object. This operator has been available for Observables (and Flowables) from the beginning of the Rx API. The methods return Single<Notification<T>>.

To complement, the dematerialize operator is only defined for Single and results in a Maybe.

If accepted, I'll draw the correct marble diagrams for them in a separate PR.

Resolves: #6272

@codecov
Copy link

codecov bot commented Nov 1, 2018

Codecov Report

Merging #6278 into 2.x will decrease coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@             Coverage Diff              @@
##                2.x    #6278      +/-   ##
============================================
- Coverage     98.25%   98.22%   -0.03%     
- Complexity     6259     6277      +18     
============================================
  Files           667      672       +5     
  Lines         44887    44954      +67     
  Branches       6213     6216       +3     
============================================
+ Hits          44104    44158      +54     
- Misses          247      258      +11     
- Partials        536      538       +2
Impacted Files Coverage Δ Complexity Δ
...nal/operators/mixed/MaterializeSingleObserver.java 100% <100%> (ø) 8 <8> (?)
.../operators/completable/CompletableMaterialize.java 100% <100%> (ø) 2 <2> (?)
...vex/internal/operators/maybe/MaybeMaterialize.java 100% <100%> (ø) 2 <2> (?)
src/main/java/io/reactivex/Completable.java 100% <100%> (ø) 120 <1> (+1) ⬆️
...x/internal/operators/single/SingleMaterialize.java 100% <100%> (ø) 2 <2> (?)
src/main/java/io/reactivex/Single.java 100% <100%> (ø) 148 <2> (+2) ⬆️
...internal/operators/single/SingleDematerialize.java 100% <100%> (ø) 2 <2> (?)
src/main/java/io/reactivex/Maybe.java 100% <100%> (ø) 172 <1> (+1) ⬆️
...ex/internal/operators/flowable/FlowableCreate.java 90.32% <0%> (-7.42%) 6% <0%> (ø)
...reactivex/internal/operators/single/SingleAmb.java 96.36% <0%> (-3.64%) 9% <0%> (-1%)
... and 30 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c3cfb5a...1ffb12d. Read the comment docs.

Copy link
Collaborator

@vanniktech vanniktech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to materialize

Mixed feelings about dematerialize

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@Experimental
public final <T2> Maybe<T2> dematerialize() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this API very awkward since it's available on every type but should only be used on Single<Notification<T>>. I don't have a better suggestion though. Except defining it yourself and using a Kotlin extension function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been the workaround for Observable.dematerialize too.

The alternative is to have the user select the notification:

Maybe<R> dematerialize(Function<T, Notification<R>> selector);

thus if you have a Single<Notification<T>>, you only need an identity selector:

Single<Notification<T>> source = ...
Maybe<T> source.dematerialize(v -> v);

However, this selector pattern is not an established one in RxJava right now. We could go for this but then the other existing dematerialize operators should also get a selector overload.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about dematerialize, then I guess we stick to that convention. Providing a mapper sounds good. Then maybe we could deprecate the current dematerialize in Observable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay then. I'll change this to use the selector and post a separate PR for adding a selector variant to Observable/Flowable and deprecate the type-fragile versions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

@akarnokd
Copy link
Member Author

akarnokd commented Nov 1, 2018

/cc @artem-zinnatullin @davidmoten

import io.reactivex.subjects.SingleSubject;

public class SingleDematerializeTest {

@Test
public void success() {
Single.just(Notification.createOnNext(1))
.<Integer>dematerialize()
.dematerialize(Functions.<Notification<Integer>>identity())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad the identity function is inside an internal package :(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose most users now can use lambdas in their project so this is just v -> v for them. Only we are still so unlucky to use such helper methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants