Skip to content

Add the cast operator to Single. #5332

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

Merged
merged 6 commits into from
May 8, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/java/rx/Single.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,21 @@ private static <T> Observable<T> asObservable(Single<T> t) {
* *********************************************************************************************************
*/

/**
* Casts the success value of the current Single into the target type or signals a
* ClassCastException if not compatible.
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code cast} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <R> the target type
* @param klass the type token to use for casting the success result from the current Single
* @return the new Single instance
*/
public final <R> Single<R> cast(final Class<R> klass) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: param doesn't need final

Copy link
Author

Choose a reason for hiding this comment

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

@JakeWharton I was following the example of Observable.cast(). Would you like me to remove final from here or shall I leave it to remain consistent?

Copy link
Member

Choose a reason for hiding this comment

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

Please add @Experimental and @since 1.3.1 - experimental to the javadoc

return map(new SingleOperatorCast<T, R>(klass));
}

/**
* Returns an Observable that emits the items emitted by two Singles, one after the other.
* <p>
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/rx/internal/operators/SingleOperatorCast.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copy link

Choose a reason for hiding this comment

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

Probably want to fix these copyright notices :)

Copy link
Member

Choose a reason for hiding this comment

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

@dano Thanks!

Copy link
Author

Choose a reason for hiding this comment

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

Thanks @dano. IntelliJ default settings getting the better of me again.

* This is the confidential unpublished intellectual property of EMC Corporation,
* and includes without limitation exclusive copyright and trade secret rights
* of EMC throughout the world.
*/
package rx.internal.operators;

import rx.functions.Func1;

/**
* Converts the element of a Single to the specified type.
* @param <T> the input value type
* @param <R> the output value type
*/
public class SingleOperatorCast<T, R> implements Func1<T, R> {

final Class<R> castClass;
Copy link
Member

Choose a reason for hiding this comment

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

4 spaces.

Copy link
Author

Choose a reason for hiding this comment

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

Sure. Updated to match the code style.


public SingleOperatorCast(Class<R> castClass) {
this.castClass = castClass;
}

@Override
public R call(T t) {
return castClass.cast(t);
}
}
42 changes: 42 additions & 0 deletions src/test/java/rx/internal/operators/SingleOperatorCastTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* This is the confidential unpublished intellectual property of EMC Corporation,
Copy link
Member

Choose a reason for hiding this comment

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

This too.

* and includes without limitation exclusive copyright and trade secret rights
* of EMC throughout the world.
*/
package rx.internal.operators;
;
import org.junit.Test;
import rx.Observer;
import rx.Single;

import static org.mockito.Mockito.*;

public class SingleOperatorCastTest {

@Test
public void testSingleCast() {
Single<?> source = Single.just(1);
Single<Integer> single = source.cast(Integer.class);

@SuppressWarnings("unchecked")
Observer<Integer> observer = mock(Observer.class);
single.subscribe(observer);
verify(observer, times(1)).onNext(1);
verify(observer, times(1)).onNext(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be onNext(2), same mistake in OperatorCastTest as well.

Copy link
Author

Choose a reason for hiding this comment

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

@artem-zinnatullin I agree that in OperatorCastTest the second invocation should use 2. However, here I think the second invocation is actually unnecessary because only one item gets emitted from the Single. I can remove this line since it is not needed.

verify(observer, never()).onError(
org.mockito.Matchers.any(Throwable.class));
verify(observer, times(1)).onCompleted();
}

@Test
public void testSingleCastWithWrongType() {
Single<?> source = Single.just(1);
Single<Boolean> single = source.cast(Boolean.class);

@SuppressWarnings("unchecked")
Observer<Boolean> observer = mock(Observer.class);
single.subscribe(observer);
verify(observer, times(1)).onError(
org.mockito.Matchers.any(ClassCastException.class));
}
}