package com.kickstarter.libs.rx.transformers;
import android.support.annotation.NonNull;
import com.kickstarter.services.ApiException;
import com.kickstarter.services.apiresponses.ErrorEnvelope;
import rx.Observable;
import rx.functions.Action1;
import rx.subjects.PublishSubject;
public final class Transformers {
private Transformers() {}
/**
* Transforms `null` values emitted from an observable into `theDefault`.
*/
public static @NonNull <T> CoalesceTransformer<T> coalesce(final @NonNull T theDefault) {
return new CoalesceTransformer<>(theDefault);
}
/**
* Emits when a materialized stream is completed.
*/
public static @NonNull <T> CompletedTransformer<T> completed() {
return new CompletedTransformer<>();
}
/**
* Emits when an error is thrown in a materialized stream.
*/
public static @NonNull <T> ErrorsTransformer<T> errors() {
return new ErrorsTransformer<>();
}
/**
* Prevents an observable from erroring by chaining `onErrorResumeNext`.
*/
public static <T> NeverErrorTransformer<T> neverError() {
return new NeverErrorTransformer<>();
}
/**
* Prevents an observable from erroring by chaining `onErrorResumeNext`,
* and any errors that occur will be piped into the supplied errors publish
* subject. `null` values will never be sent to the publish subject.
*
* @deprecated Use {@link Observable#materialize()} instead.
*/
@Deprecated
public static <T> NeverErrorTransformer<T> pipeErrorsTo(final @NonNull PublishSubject<Throwable> errorSubject) {
return new NeverErrorTransformer<>(errorSubject::onNext);
}
/**
* Prevents an observable from erroring by chaining `onErrorResumeNext`,
* and any errors that occur will be piped into the supplied errors action.
* `null` values will never be sent to the publish subject.
*
* @deprecated Use {@link Observable#materialize()} instead.
*/
@Deprecated
public static <T> NeverErrorTransformer<T> pipeErrorsTo(final @NonNull Action1<Throwable> errorAction) {
return new NeverErrorTransformer<>(errorAction);
}
/**
* Prevents an observable from erroring on any {@link ApiException} exceptions.
*/
public static <T> NeverApiErrorTransformer<T> neverApiError() {
return new NeverApiErrorTransformer<>();
}
/**
* Prevents an observable from erroring on any {@link ApiException} exceptions,
* and any errors that do occur will be piped into the supplied
* errors publish subject. `null` values will never be sent to
* the publish subject.
*
* @deprecated Use {@link Observable#materialize()} instead.
*/
@Deprecated
public static <T> NeverApiErrorTransformer<T> pipeApiErrorsTo(final @NonNull PublishSubject<ErrorEnvelope> errorSubject) {
return new NeverApiErrorTransformer<>(errorSubject::onNext);
}
/**
* Prevents an observable from erroring on any {@link ApiException} exceptions,
* and any errors that do occur will be piped into the supplied
* errors actions. `null` values will never be sent to the action.
*
* @deprecated Use {@link Observable#materialize()} instead.
*/
@Deprecated
public static <T> NeverApiErrorTransformer<T> pipeApiErrorsTo(final @NonNull Action1<ErrorEnvelope> errorAction) {
return new NeverApiErrorTransformer<>(errorAction);
}
/**
* Emits the latest value of the source observable whenever the `when`
* observable emits.
*/
public static <S, T> TakeWhenTransformer<S, T> takeWhen(final @NonNull Observable<T> when) {
return new TakeWhenTransformer<>(when);
}
/**
* Emits the latest value of the source `when` observable whenever the
* `when` observable emits.
*/
public static <S, T> TakePairWhenTransformer<S, T> takePairWhen(final @NonNull Observable<T> when) {
return new TakePairWhenTransformer<>(when);
}
/**
* Zips two observables up into an observable of pairs.
*/
public static <S, T> ZipPairTransformer<S, T> zipPair(final @NonNull Observable<T> second) {
return new ZipPairTransformer<>(second);
}
/**
* Emits the latest values from two observables whenever either emits.
*/
public static <S, T> CombineLatestPairTransformer<S, T> combineLatestPair(final @NonNull Observable<T> second) {
return new CombineLatestPairTransformer<>(second);
}
/**
* Waits until `until` emits one single item and then switches context to the source. This
* can be useful to delay work until a user logs in:
*
* ```
* somethingThatRequiresAuth
* .compose(waitUntil(currentUser.loggedInUser()))
* .subscribe(show)
* ```
*/
public static @NonNull <T, R> WaitUntilTransformer<T, R> waitUntil(final @NonNull Observable<R> until) {
return new WaitUntilTransformer<>(until);
}
/**
* Converts an observable of any type into an observable of `null`s. This is useful for forcing
* Java's type system into knowing we have a stream of `Void`. Simply doing `.map(__ -> null)`
* is not enough since Java doesn't know if that is a `null` String, Integer, Void, etc.
*
* This transformer allows the following pattern:
*
* ```
* myObservable
* .compose(takeWhen(click))
* .compose(ignoreValues())
* .subscribe(subject::onNext)
* ```
*/
public static @NonNull <S> IgnoreValuesTransformer<S> ignoreValues() {
return new IgnoreValuesTransformer<>();
}
/**
* Emits the number of times the source has emitted for every emission of the source. The
* first emitted value will be `1`.
*/
public static @NonNull <T> IncrementalCountTransformer<T> incrementalCount() {
return new IncrementalCountTransformer<>();
}
/**
* Emits an observable of values from a materialized stream.
*/
public static @NonNull <T> ValuesTransformer<T> values() {
return new ValuesTransformer<>();
}
/**
* If called on the main thread, schedule the work immediately. Otherwise delay execution of the work by adding it
* to a message queue, where it will be executed on the main thread.
*
* This is particularly useful for RecyclerViews; if subscriptions in these views are delayed for a frame, then
* the view temporarily shows recycled content and frame rate stutters. To address that, we can use `observeForUI()`
* to execute the work immediately rather than wait for a frame.
*/
public static @NonNull <T> ObserveForUITransformer<T> observeForUI() {
return new ObserveForUITransformer<>();
}
}