From 7b9a3217a18839dfca4742e379fe6569ffdd9c62 Mon Sep 17 00:00:00 2001 From: sergdort Date: Sat, 19 Aug 2017 20:15:05 +0100 Subject: [PATCH 1/4] Move Traits in separate file --- Rx.xcodeproj/project.pbxproj | 30 +++ RxSwift/Traits/Completable.swift | 87 ++++++++ RxSwift/Traits/Maybe.swift | 96 +++++++++ RxSwift/Traits/PrimitiveSequence.swift | 263 ------------------------- RxSwift/Traits/Single.swift | 89 +++++++++ 5 files changed, 302 insertions(+), 263 deletions(-) create mode 100644 RxSwift/Traits/Completable.swift create mode 100644 RxSwift/Traits/Maybe.swift create mode 100644 RxSwift/Traits/Single.swift diff --git a/Rx.xcodeproj/project.pbxproj b/Rx.xcodeproj/project.pbxproj index 4ca79e19..e8a42b87 100644 --- a/Rx.xcodeproj/project.pbxproj +++ b/Rx.xcodeproj/project.pbxproj @@ -21,6 +21,18 @@ 1AF67DA61CED430100C310FA /* ReplaySubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF67DA51CED430100C310FA /* ReplaySubjectTest.swift */; }; 1AF67DA71CED430100C310FA /* ReplaySubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF67DA51CED430100C310FA /* ReplaySubjectTest.swift */; }; 1AF67DA81CED430100C310FA /* ReplaySubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AF67DA51CED430100C310FA /* ReplaySubjectTest.swift */; }; + 25F6ECBC1F48C366008552FA /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBB1F48C366008552FA /* Maybe.swift */; }; + 25F6ECBE1F48C373008552FA /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBD1F48C373008552FA /* Completable.swift */; }; + 25F6ECC01F48C37C008552FA /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBF1F48C37C008552FA /* Single.swift */; }; + 25F6ECC11F48C405008552FA /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBB1F48C366008552FA /* Maybe.swift */; }; + 25F6ECC21F48C405008552FA /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBD1F48C373008552FA /* Completable.swift */; }; + 25F6ECC31F48C405008552FA /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBF1F48C37C008552FA /* Single.swift */; }; + 25F6ECC41F48C406008552FA /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBB1F48C366008552FA /* Maybe.swift */; }; + 25F6ECC51F48C406008552FA /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBD1F48C373008552FA /* Completable.swift */; }; + 25F6ECC61F48C406008552FA /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBF1F48C37C008552FA /* Single.swift */; }; + 25F6ECC71F48C407008552FA /* Maybe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBB1F48C366008552FA /* Maybe.swift */; }; + 25F6ECC81F48C407008552FA /* Completable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBD1F48C373008552FA /* Completable.swift */; }; + 25F6ECC91F48C407008552FA /* Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F6ECBF1F48C37C008552FA /* Single.swift */; }; 271A97411CFC996B00D64125 /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 271A97401CFC996B00D64125 /* UIViewController+Rx.swift */; }; 271A97441CFC9F7B00D64125 /* UIViewController+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 271A97421CFC99FE00D64125 /* UIViewController+RxTests.swift */; }; 4613456F1D9A4467001ABAF2 /* UIWebView+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4613456E1D9A4467001ABAF2 /* UIWebView+RxTests.swift */; }; @@ -1680,6 +1692,9 @@ 0BA9496B1E224B9C0036DD06 /* AsyncSubjectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncSubjectTests.swift; sourceTree = ""; }; 1AF67DA11CED420A00C310FA /* PublishSubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishSubjectTest.swift; sourceTree = ""; }; 1AF67DA51CED430100C310FA /* ReplaySubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplaySubjectTest.swift; sourceTree = ""; }; + 25F6ECBB1F48C366008552FA /* Maybe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Maybe.swift; sourceTree = ""; }; + 25F6ECBD1F48C373008552FA /* Completable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Completable.swift; sourceTree = ""; }; + 25F6ECBF1F48C37C008552FA /* Single.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Single.swift; sourceTree = ""; }; 271A97401CFC996B00D64125 /* UIViewController+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Rx.swift"; sourceTree = ""; }; 271A97421CFC99FE00D64125 /* UIViewController+RxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+RxTests.swift"; sourceTree = ""; }; 4613456E1D9A4467001ABAF2 /* UIWebView+RxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIWebView+RxTests.swift"; sourceTree = ""; }; @@ -2554,6 +2569,9 @@ isa = PBXGroup; children = ( C81A09861E6C702700900B3B /* PrimitiveSequence.swift */, + 25F6ECBF1F48C37C008552FA /* Single.swift */, + 25F6ECBB1F48C366008552FA /* Maybe.swift */, + 25F6ECBD1F48C373008552FA /* Completable.swift */, C89814751E75A18A0035949C /* PrimitiveSequence+Zip+arity.tt */, C89814771E75A7D70035949C /* PrimitiveSequence+Zip+arity.swift */, C8A53ADF1F09178700490535 /* Completable+AndThen.swift */, @@ -4636,6 +4654,7 @@ C8093CCC1B8A72BE0088E94D /* ConnectableObservableType.swift in Sources */, C820A8811EB4DA5A00D431BC /* Filter.swift in Sources */, C820A86D1EB4DA5A00D431BC /* ElementAt.swift in Sources */, + 25F6ECC11F48C405008552FA /* Maybe.swift in Sources */, C83D73BD1C1DBAEE003DC470 /* InvocableScheduledItem.swift in Sources */, C8093CE61B8A72BE0088E94D /* NopDisposable.swift in Sources */, C89814791E75A7E70035949C /* PrimitiveSequence+Zip+arity.swift in Sources */, @@ -4681,6 +4700,7 @@ C83D73C11C1DBAEE003DC470 /* InvocableType.swift in Sources */, C820A9151EB4DA5A00D431BC /* ToArray.swift in Sources */, C820A8751EB4DA5A00D431BC /* SkipWhile.swift in Sources */, + 25F6ECC21F48C405008552FA /* Completable.swift in Sources */, C820A91D1EB4DA5A00D431BC /* AsSingle.swift in Sources */, C8093D741B8A72BE0088E94D /* ObserverBase.swift in Sources */, C85106891C2D550E0075150C /* String+Rx.swift in Sources */, @@ -4733,6 +4753,7 @@ C820A8691EB4DA5A00D431BC /* SingleAsync.swift in Sources */, C81A09881E6C702700900B3B /* PrimitiveSequence.swift in Sources */, C8093CD61B8A72BE0088E94D /* AnonymousDisposable.swift in Sources */, + 25F6ECC31F48C405008552FA /* Single.swift in Sources */, C820A8A11EB4DA5A00D431BC /* Do.swift in Sources */, C8093D901B8A72BE0088E94D /* ConcurrentDispatchQueueScheduler.swift in Sources */, C820A83D1EB4DA5900D431BC /* Window.swift in Sources */, @@ -4870,6 +4891,7 @@ C8093CCB1B8A72BE0088E94D /* ConnectableObservableType.swift in Sources */, C820A8801EB4DA5A00D431BC /* Filter.swift in Sources */, C820A86C1EB4DA5A00D431BC /* ElementAt.swift in Sources */, + 25F6ECBC1F48C366008552FA /* Maybe.swift in Sources */, C83D73BC1C1DBAEE003DC470 /* InvocableScheduledItem.swift in Sources */, C8093CE51B8A72BE0088E94D /* NopDisposable.swift in Sources */, C86781741DB8129E00B2029A /* InfiniteSequence.swift in Sources */, @@ -4915,6 +4937,7 @@ C85106881C2D550E0075150C /* String+Rx.swift in Sources */, C820A9141EB4DA5A00D431BC /* ToArray.swift in Sources */, C820A8741EB4DA5A00D431BC /* SkipWhile.swift in Sources */, + 25F6ECBE1F48C373008552FA /* Completable.swift in Sources */, C820A91C1EB4DA5A00D431BC /* AsSingle.swift in Sources */, C8BF34CF1C2E426800416CAE /* Platform.Linux.swift in Sources */, C8093D791B8A72BE0088E94D /* TailRecursiveSink.swift in Sources */, @@ -4967,6 +4990,7 @@ C820A8681EB4DA5A00D431BC /* SingleAsync.swift in Sources */, C81A09871E6C702700900B3B /* PrimitiveSequence.swift in Sources */, C8093D8F1B8A72BE0088E94D /* ConcurrentDispatchQueueScheduler.swift in Sources */, + 25F6ECC01F48C37C008552FA /* Single.swift in Sources */, C820A8A01EB4DA5A00D431BC /* Do.swift in Sources */, C8093D9F1B8A72BE0088E94D /* BehaviorSubject.swift in Sources */, C820A83C1EB4DA5900D431BC /* Window.swift in Sources */, @@ -5028,6 +5052,7 @@ C8F0BF931BBBFB8B001B112F /* ConnectableObservableType.swift in Sources */, C820A8831EB4DA5A00D431BC /* Filter.swift in Sources */, C820A86F1EB4DA5A00D431BC /* ElementAt.swift in Sources */, + 25F6ECC71F48C407008552FA /* Maybe.swift in Sources */, C83D73BF1C1DBAEE003DC470 /* InvocableScheduledItem.swift in Sources */, C8F0BF951BBBFB8B001B112F /* NopDisposable.swift in Sources */, C898147B1E75A7E80035949C /* PrimitiveSequence+Zip+arity.swift in Sources */, @@ -5073,6 +5098,7 @@ C83D73C31C1DBAEE003DC470 /* InvocableType.swift in Sources */, C820A9171EB4DA5A00D431BC /* ToArray.swift in Sources */, C820A8771EB4DA5A00D431BC /* SkipWhile.swift in Sources */, + 25F6ECC81F48C407008552FA /* Completable.swift in Sources */, C820A91F1EB4DA5A00D431BC /* AsSingle.swift in Sources */, C8F0BFAF1BBBFB8B001B112F /* ObserverBase.swift in Sources */, C851068B1C2D550E0075150C /* String+Rx.swift in Sources */, @@ -5125,6 +5151,7 @@ C820A86B1EB4DA5A00D431BC /* SingleAsync.swift in Sources */, C81A098A1E6C702700900B3B /* PrimitiveSequence.swift in Sources */, C8F0BFD01BBBFB8B001B112F /* AnonymousDisposable.swift in Sources */, + 25F6ECC91F48C407008552FA /* Single.swift in Sources */, C820A8A31EB4DA5A00D431BC /* Do.swift in Sources */, C8F0BFD11BBBFB8B001B112F /* ConcurrentDispatchQueueScheduler.swift in Sources */, C820A83F1EB4DA5900D431BC /* Window.swift in Sources */, @@ -5384,6 +5411,7 @@ D2EBEADF1BB9B697003A27DC /* Errors.swift in Sources */, C820A8821EB4DA5A00D431BC /* Filter.swift in Sources */, C820A86E1EB4DA5A00D431BC /* ElementAt.swift in Sources */, + 25F6ECC41F48C406008552FA /* Maybe.swift in Sources */, C83D73BE1C1DBAEE003DC470 /* InvocableScheduledItem.swift in Sources */, D2EBEAF01BB9B6AE003A27DC /* AnonymousDisposable.swift in Sources */, D2EBEAEB1BB9B69E003A27DC /* AsyncLock.swift in Sources */, @@ -5429,6 +5457,7 @@ C820A89A1EB4DA5A00D431BC /* Catch.swift in Sources */, D2EBEB421BB9B6DE003A27DC /* ReplaySubject.swift in Sources */, C820A9161EB4DA5A00D431BC /* ToArray.swift in Sources */, + 25F6ECC51F48C406008552FA /* Completable.swift in Sources */, C820A8761EB4DA5A00D431BC /* SkipWhile.swift in Sources */, C820A91E1EB4DA5A00D431BC /* AsSingle.swift in Sources */, D2EBEB381BB9B6D8003A27DC /* ConcurrentDispatchQueueScheduler.swift in Sources */, @@ -5481,6 +5510,7 @@ C820A86A1EB4DA5A00D431BC /* SingleAsync.swift in Sources */, D2EBEADD1BB9B697003A27DC /* ConnectableObservableType.swift in Sources */, D2EBEB361BB9B6D2003A27DC /* TailRecursiveSink.swift in Sources */, + 25F6ECC61F48C406008552FA /* Single.swift in Sources */, C820A8A21EB4DA5A00D431BC /* Do.swift in Sources */, D2EBEAE91BB9B697003A27DC /* RxMutableBox.swift in Sources */, C820A83E1EB4DA5900D431BC /* Window.swift in Sources */, diff --git a/RxSwift/Traits/Completable.swift b/RxSwift/Traits/Completable.swift new file mode 100644 index 00000000..e086d4f3 --- /dev/null +++ b/RxSwift/Traits/Completable.swift @@ -0,0 +1,87 @@ +// +// Completable.swift +// Rx +// +// Created by sergdort on 19/08/2017. +// Copyright © 2017 Krunoslav Zaher. All rights reserved. +// + +/// Sequence containing 0 elements +public enum CompletableTrait { } +/// Represents a push style sequence containing 0 elements. +public typealias Completable = PrimitiveSequence + +public enum CompletableEvent { + /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) + case error(Swift.Error) + + /// Sequence completed successfully. + case completed +} + +public extension PrimitiveSequenceType where TraitType == CompletableTrait, ElementType == Swift.Never { + public typealias CompletableObserver = (CompletableEvent) -> () + + /** + Creates an observable sequence from a specified subscribe method implementation. + + - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) + + - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. + - returns: The observable sequence with the specified implementation for the `subscribe` method. + */ + public static func create(subscribe: @escaping (@escaping CompletableObserver) -> Disposable) -> PrimitiveSequence { + let source = Observable.create { observer in + return subscribe { event in + switch event { + case .error(let error): + observer.on(.error(error)) + case .completed: + observer.on(.completed) + } + } + } + + return PrimitiveSequence(raw: source) + } + + /** + Subscribes `observer` to receive events for this sequence. + + - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. + */ + public func subscribe(_ observer: @escaping (CompletableEvent) -> ()) -> Disposable { + var stopped = false + return self.primitiveSequence.asObservable().subscribe { event in + if stopped { return } + stopped = true + + switch event { + case .next: + rxFatalError("Completables can't emit values") + case .error(let error): + observer(.error(error)) + case .completed: + observer(.completed) + } + } + } + + /** + Subscribes a completion handler and an error handler for this sequence. + + - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - returns: Subscription object used to unsubscribe from the observable sequence. + */ + public func subscribe(onCompleted: (() -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil) -> Disposable { + return self.primitiveSequence.subscribe { event in + switch event { + case .error(let error): + onError?(error) + case .completed: + onCompleted?() + } + } + } +} diff --git a/RxSwift/Traits/Maybe.swift b/RxSwift/Traits/Maybe.swift new file mode 100644 index 00000000..d9234ad9 --- /dev/null +++ b/RxSwift/Traits/Maybe.swift @@ -0,0 +1,96 @@ +// +// Maybe.swift +// Rx +// +// Created by sergdort on 19/08/2017. +// Copyright © 2017 Krunoslav Zaher. All rights reserved. +// + +/// Sequence containing 0 or 1 elements +public enum MaybeTrait { } +/// Represents a push style sequence containing 0 or 1 element. +public typealias Maybe = PrimitiveSequence + +public enum MaybeEvent { + /// One and only sequence element is produced. (underlying observable sequence emits: `.next(Element)`, `.completed`) + case success(Element) + + /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) + case error(Swift.Error) + + /// Sequence completed successfully. + case completed +} + +public extension PrimitiveSequenceType where TraitType == MaybeTrait { + public typealias MaybeObserver = (MaybeEvent) -> () + + /** + Creates an observable sequence from a specified subscribe method implementation. + + - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) + + - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. + - returns: The observable sequence with the specified implementation for the `subscribe` method. + */ + public static func create(subscribe: @escaping (@escaping MaybeObserver) -> Disposable) -> PrimitiveSequence { + let source = Observable.create { observer in + return subscribe { event in + switch event { + case .success(let element): + observer.on(.next(element)) + observer.on(.completed) + case .error(let error): + observer.on(.error(error)) + case .completed: + observer.on(.completed) + } + } + } + + return PrimitiveSequence(raw: source) + } + + /** + Subscribes `observer` to receive events for this sequence. + + - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. + */ + public func subscribe(_ observer: @escaping (MaybeEvent) -> ()) -> Disposable { + var stopped = false + return self.primitiveSequence.asObservable().subscribe { event in + if stopped { return } + stopped = true + + switch event { + case .next(let element): + observer(.success(element)) + case .error(let error): + observer(.error(error)) + case .completed: + observer(.completed) + } + } + } + + /** + Subscribes a success handler, an error handler, and a completion handler for this sequence. + + - parameter onSuccess: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. + - returns: Subscription object used to unsubscribe from the observable sequence. + */ + public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil) -> Disposable { + return self.primitiveSequence.subscribe { event in + switch event { + case .success(let element): + onSuccess?(element) + case .error(let error): + onError?(error) + case .completed: + onCompleted?() + } + } + } +} diff --git a/RxSwift/Traits/PrimitiveSequence.swift b/RxSwift/Traits/PrimitiveSequence.swift index 3261e420..740bce7d 100644 --- a/RxSwift/Traits/PrimitiveSequence.swift +++ b/RxSwift/Traits/PrimitiveSequence.swift @@ -15,21 +15,6 @@ public struct PrimitiveSequence { } } -/// Sequence containing exactly 1 element -public enum SingleTrait { } -/// Represents a push style sequence containing 1 element. -public typealias Single = PrimitiveSequence - -/// Sequence containing 0 or 1 elements -public enum MaybeTrait { } -/// Represents a push style sequence containing 0 or 1 element. -public typealias Maybe = PrimitiveSequence - -/// Sequence containing 0 elements -public enum CompletableTrait { } -/// Represents a push style sequence containing 0 elements. -public typealias Completable = PrimitiveSequence - /// Observable sequences containing 0 or 1 element public protocol PrimitiveSequenceType { /// Additional constraints @@ -69,254 +54,6 @@ extension PrimitiveSequence: ObservableConvertibleType { } } -// - -public enum SingleEvent { - /// One and only sequence element is produced. (underlying observable sequence emits: `.next(Element)`, `.completed`) - case success(Element) - - /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) - case error(Swift.Error) -} - -extension PrimitiveSequenceType where TraitType == SingleTrait { - public typealias SingleObserver = (SingleEvent) -> () - - /** - Creates an observable sequence from a specified subscribe method implementation. - - - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) - - - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - - returns: The observable sequence with the specified implementation for the `subscribe` method. - */ - public static func create(subscribe: @escaping (@escaping SingleObserver) -> Disposable) -> PrimitiveSequence { - let source = Observable.create { observer in - return subscribe { event in - switch event { - case .success(let element): - observer.on(.next(element)) - observer.on(.completed) - case .error(let error): - observer.on(.error(error)) - } - } - } - - return PrimitiveSequence(raw: source) - } - - - /** - Subscribes `observer` to receive events for this sequence. - - - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. - */ - public func subscribe(_ observer: @escaping (SingleEvent) -> ()) -> Disposable { - var stopped = false - return self.primitiveSequence.asObservable().subscribe { event in - if stopped { return } - stopped = true - - switch event { - case .next(let element): - observer(.success(element)) - case .error(let error): - observer(.error(error)) - case .completed: - rxFatalErrorInDebug("Singles can't emit a completion event") - } - } - } - - /** - Subscribes a success handler, and an error handler for this sequence. - - - parameter onSuccess: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil) -> Disposable { - return self.primitiveSequence.subscribe { event in - switch event { - case .success(let element): - onSuccess?(element) - case .error(let error): - onError?(error) - } - } - } -} - -// - -// - -public enum MaybeEvent { - /// One and only sequence element is produced. (underlying observable sequence emits: `.next(Element)`, `.completed`) - case success(Element) - - /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) - case error(Swift.Error) - - /// Sequence completed successfully. - case completed -} - -public extension PrimitiveSequenceType where TraitType == MaybeTrait { - public typealias MaybeObserver = (MaybeEvent) -> () - - /** - Creates an observable sequence from a specified subscribe method implementation. - - - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) - - - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - - returns: The observable sequence with the specified implementation for the `subscribe` method. - */ - public static func create(subscribe: @escaping (@escaping MaybeObserver) -> Disposable) -> PrimitiveSequence { - let source = Observable.create { observer in - return subscribe { event in - switch event { - case .success(let element): - observer.on(.next(element)) - observer.on(.completed) - case .error(let error): - observer.on(.error(error)) - case .completed: - observer.on(.completed) - } - } - } - - return PrimitiveSequence(raw: source) - } - - /** - Subscribes `observer` to receive events for this sequence. - - - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. - */ - public func subscribe(_ observer: @escaping (MaybeEvent) -> ()) -> Disposable { - var stopped = false - return self.primitiveSequence.asObservable().subscribe { event in - if stopped { return } - stopped = true - - switch event { - case .next(let element): - observer(.success(element)) - case .error(let error): - observer(.error(error)) - case .completed: - observer(.completed) - } - } - } - - /** - Subscribes a success handler, an error handler, and a completion handler for this sequence. - - - parameter onSuccess: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil) -> Disposable { - return self.primitiveSequence.subscribe { event in - switch event { - case .success(let element): - onSuccess?(element) - case .error(let error): - onError?(error) - case .completed: - onCompleted?() - } - } - } -} - -// - -// - -public enum CompletableEvent { - /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) - case error(Swift.Error) - - /// Sequence completed successfully. - case completed -} - -public extension PrimitiveSequenceType where TraitType == CompletableTrait, ElementType == Swift.Never { - public typealias CompletableObserver = (CompletableEvent) -> () - - /** - Creates an observable sequence from a specified subscribe method implementation. - - - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) - - - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - - returns: The observable sequence with the specified implementation for the `subscribe` method. - */ - public static func create(subscribe: @escaping (@escaping CompletableObserver) -> Disposable) -> PrimitiveSequence { - let source = Observable.create { observer in - return subscribe { event in - switch event { - case .error(let error): - observer.on(.error(error)) - case .completed: - observer.on(.completed) - } - } - } - - return PrimitiveSequence(raw: source) - } - - /** - Subscribes `observer` to receive events for this sequence. - - - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. - */ - public func subscribe(_ observer: @escaping (CompletableEvent) -> ()) -> Disposable { - var stopped = false - return self.primitiveSequence.asObservable().subscribe { event in - if stopped { return } - stopped = true - - switch event { - case .next: - rxFatalError("Completables can't emit values") - case .error(let error): - observer(.error(error)) - case .completed: - observer(.completed) - } - } - } - - /** - Subscribes a completion handler and an error handler for this sequence. - - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - returns: Subscription object used to unsubscribe from the observable sequence. - */ - public func subscribe(onCompleted: (() -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil) -> Disposable { - return self.primitiveSequence.subscribe { event in - switch event { - case .error(let error): - onError?(error) - case .completed: - onCompleted?() - } - } - } -} - -// - extension PrimitiveSequence { /** Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes. diff --git a/RxSwift/Traits/Single.swift b/RxSwift/Traits/Single.swift new file mode 100644 index 00000000..8ce0f6a1 --- /dev/null +++ b/RxSwift/Traits/Single.swift @@ -0,0 +1,89 @@ +// +// Single.swift +// Rx +// +// Created by sergdort on 19/08/2017. +// Copyright © 2017 Krunoslav Zaher. All rights reserved. +// + +/// Sequence containing exactly 1 element +public enum SingleTrait { } +/// Represents a push style sequence containing 1 element. +public typealias Single = PrimitiveSequence + +public enum SingleEvent { + /// One and only sequence element is produced. (underlying observable sequence emits: `.next(Element)`, `.completed`) + case success(Element) + + /// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`) + case error(Swift.Error) +} + +extension PrimitiveSequenceType where TraitType == SingleTrait { + public typealias SingleObserver = (SingleEvent) -> () + + /** + Creates an observable sequence from a specified subscribe method implementation. + + - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html) + + - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. + - returns: The observable sequence with the specified implementation for the `subscribe` method. + */ + public static func create(subscribe: @escaping (@escaping SingleObserver) -> Disposable) -> PrimitiveSequence { + let source = Observable.create { observer in + return subscribe { event in + switch event { + case .success(let element): + observer.on(.next(element)) + observer.on(.completed) + case .error(let error): + observer.on(.error(error)) + } + } + } + + return PrimitiveSequence(raw: source) + } + + + /** + Subscribes `observer` to receive events for this sequence. + + - returns: Subscription for `observer` that can be used to cancel production of sequence elements and free resources. + */ + public func subscribe(_ observer: @escaping (SingleEvent) -> ()) -> Disposable { + var stopped = false + return self.primitiveSequence.asObservable().subscribe { event in + if stopped { return } + stopped = true + + switch event { + case .next(let element): + observer(.success(element)) + case .error(let error): + observer(.error(error)) + case .completed: + rxFatalErrorInDebug("Singles can't emit a completion event") + } + } + } + + /** + Subscribes a success handler, and an error handler for this sequence. + + - parameter onSuccess: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - returns: Subscription object used to unsubscribe from the observable sequence. + */ + public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil) -> Disposable { + return self.primitiveSequence.subscribe { event in + switch event { + case .success(let element): + onSuccess?(element) + case .error(let error): + onError?(error) + } + } + } +} From 0ca7f2c3caca30e002e4df4378bc871218036491 Mon Sep 17 00:00:00 2001 From: sergdort Date: Sat, 19 Aug 2017 21:20:48 +0100 Subject: [PATCH 2/4] Move appropriate operators to correct traits --- .jazzy.yml | 3 + RxSwift/Traits/Completable.swift | 131 ++++++++++++- RxSwift/Traits/Maybe.swift | 143 +++++++++++++- RxSwift/Traits/PrimitiveSequence.swift | 246 +------------------------ RxSwift/Traits/Single.swift | 141 +++++++++++++- 5 files changed, 414 insertions(+), 250 deletions(-) diff --git a/.jazzy.yml b/.jazzy.yml index 81e03195..f035b753 100644 --- a/.jazzy.yml +++ b/.jazzy.yml @@ -165,8 +165,11 @@ custom_categories: - name: RxSwift/Traits children: - Completable+AndThen + - Completable + - Maybe - PrimitiveSequence+Zip+arity - PrimitiveSequence + - Single - name: RxCocoa/Common children: - ControlTarget diff --git a/RxSwift/Traits/Completable.swift b/RxSwift/Traits/Completable.swift index e086d4f3..7eb966e8 100644 --- a/RxSwift/Traits/Completable.swift +++ b/RxSwift/Traits/Completable.swift @@ -1,6 +1,6 @@ // // Completable.swift -// Rx +// RxSwift // // Created by sergdort on 19/08/2017. // Copyright © 2017 Krunoslav Zaher. All rights reserved. @@ -84,4 +84,133 @@ public extension PrimitiveSequenceType where TraitType == CompletableTrait, Elem } } } + + /** + Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. + + - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) + + - parameter onNext: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. + - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. + - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. + - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. + - returns: The source sequence with the side-effecting behavior applied. + */ + public func `do`(onError: ((Swift.Error) throws -> Void)? = nil, + onCompleted: (() throws -> Void)? = nil, + onSubscribe: (() -> ())? = nil, + onSubscribed: (() -> ())? = nil, + onDispose: (() -> ())? = nil) + -> Completable { + return Completable(raw: primitiveSequence.source.do( + onError: onError, + onCompleted: onCompleted, + onSubscribe: onSubscribe, + onSubscribed: onSubscribed, + onDispose: onDispose) + ) + } + + /** + Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. + + - seealso: [empty operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) + + - returns: An observable sequence with no elements. + */ + public static func empty() -> Completable { + return Completable(raw: Observable.empty()) + } + + /** + Concatenates the second observable sequence to `self` upon successful termination of `self`. + + - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) + + - parameter second: Second observable sequence. + - returns: An observable sequence that contains the elements of `self`, followed by those of the second sequence. + */ + public func concat(_ second: Completable) -> Completable { + return Completable.concat(primitiveSequence, second) + } + + /** + Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. + + - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) + + - returns: An observable sequence that contains the elements of each given sequence, in sequential order. + */ + public static func concat(_ sequence: S) -> Completable + where S.Iterator.Element == Completable { + let source = Observable.concat(sequence.lazy.map { $0.asObservable() }) + return Completable(raw: source) + } + + /** + Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. + + - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) + + - returns: An observable sequence that contains the elements of each given sequence, in sequential order. + */ + public static func concat(_ collection: C) -> Completable + where C.Iterator.Element == Completable { + let source = Observable.concat(collection.map { $0.asObservable() }) + return Completable(raw: source) + } + + /** + Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. + + - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) + + - returns: An observable sequence that contains the elements of each given sequence, in sequential order. + */ + public static func concat(_ sources: Completable ...) -> Completable { + let source = Observable.concat(sources.map { $0.asObservable() }) + return Completable(raw: source) + } + + /** + Merges elements from all observable sequences from collection into a single observable sequence. + + - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) + + - parameter sources: Collection of observable sequences to merge. + - returns: The observable sequence that merges the elements of the observable sequences. + */ + public static func merge(_ sources: C) -> Completable + where C.Iterator.Element == Completable { + let source = Observable.merge(sources.map { $0.asObservable() }) + return Completable(raw: source) + } + + /** + Merges elements from all observable sequences from array into a single observable sequence. + + - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) + + - parameter sources: Array of observable sequences to merge. + - returns: The observable sequence that merges the elements of the observable sequences. + */ + public static func merge(_ sources: [Completable]) -> Completable { + let source = Observable.merge(sources.map { $0.asObservable() }) + return Completable(raw: source) + } + + /** + Merges elements from all observable sequences into a single observable sequence. + + - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) + + - parameter sources: Collection of observable sequences to merge. + - returns: The observable sequence that merges the elements of the observable sequences. + */ + public static func merge(_ sources: Completable...) -> Completable { + let source = Observable.merge(sources.map { $0.asObservable() }) + return Completable(raw: source) + } } diff --git a/RxSwift/Traits/Maybe.swift b/RxSwift/Traits/Maybe.swift index d9234ad9..40d9a165 100644 --- a/RxSwift/Traits/Maybe.swift +++ b/RxSwift/Traits/Maybe.swift @@ -1,6 +1,6 @@ // // Maybe.swift -// Rx +// RxSwift // // Created by sergdort on 19/08/2017. // Copyright © 2017 Krunoslav Zaher. All rights reserved. @@ -81,7 +81,9 @@ public extension PrimitiveSequenceType where TraitType == MaybeTrait { - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - returns: Subscription object used to unsubscribe from the observable sequence. */ - public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil) -> Disposable { + public func subscribe(onSuccess: ((ElementType) -> Void)? = nil, + onError: ((Swift.Error) -> Void)? = nil, + onCompleted: (() -> Void)? = nil) -> Disposable { return self.primitiveSequence.subscribe { event in switch event { case .success(let element): @@ -93,4 +95,141 @@ public extension PrimitiveSequenceType where TraitType == MaybeTrait { } } } + + /** + Returns an observable sequence that contains a single element. + + - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) + + - parameter element: Single element in the resulting observable sequence. + - returns: An observable sequence containing the single specified element. + */ + public static func just(_ element: ElementType) -> Maybe { + return Maybe(raw: Observable.just(element)) + } + + /** + Returns an observable sequence that contains a single element. + + - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) + + - parameter element: Single element in the resulting observable sequence. + - parameter: Scheduler to send the single element on. + - returns: An observable sequence containing the single specified element. + */ + public static func just(_ element: ElementType, scheduler: ImmediateSchedulerType) -> Maybe { + return Maybe(raw: Observable.just(element, scheduler: scheduler)) + } + + /** + Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the source by. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: the source Observable shifted in time by the specified delay. + */ + public func delay(_ dueTime: RxTimeInterval, scheduler: SchedulerType) + -> Maybe { + return Maybe(raw: primitiveSequence.source.delay(dueTime, scheduler: scheduler)) + } + + /** + Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. + + - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) + + - parameter onNext: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. + - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. + - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. + - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. + - returns: The source sequence with the side-effecting behavior applied. + */ + public func `do`(onNext: ((ElementType) throws -> Void)? = nil, + onError: ((Swift.Error) throws -> Void)? = nil, + onCompleted: (() throws -> Void)? = nil, + onSubscribe: (() -> ())? = nil, + onSubscribed: (() -> ())? = nil, + onDispose: (() -> ())? = nil) + -> Maybe { + return Maybe(raw: primitiveSequence.source.do( + onNext: onNext, + onError: onError, + onCompleted: onCompleted, + onSubscribe: onSubscribe, + onSubscribed: onSubscribed, + onDispose: onDispose) + ) + } + + /** + Filters the elements of an observable sequence based on a predicate. + + - seealso: [filter operator on reactivex.io](http://reactivex.io/documentation/operators/filter.html) + + - parameter predicate: A function to test each source element for a condition. + - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. + */ + public func filter(_ predicate: @escaping (ElementType) throws -> Bool) + -> Maybe { + return Maybe(raw: primitiveSequence.source.filter(predicate)) + } + + /** + Projects each element of an observable sequence into a new form. + + - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) + + - parameter transform: A transform function to apply to each source element. + - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. + + */ + public func map(_ transform: @escaping (ElementType) throws -> R) + -> Maybe { + return Maybe(raw: primitiveSequence.source.map(transform)) + } + + /** + Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: An observable sequence with a `RxError.timeout` in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) + -> Maybe { + return Maybe(raw: primitiveSequence.source.timeout(dueTime, scheduler: scheduler)) + } + + /** + Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter other: Sequence to return in case of a timeout. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: The source sequence switching to the other sequence in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, + other: Maybe, + scheduler: SchedulerType) -> Maybe { + return Maybe(raw: primitiveSequence.source.timeout(dueTime, other: other.source, scheduler: scheduler)) + } + + /** + Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. + + - seealso: [empty operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) + + - returns: An observable sequence with no elements. + */ + public static func empty() -> Maybe { + return Maybe(raw: Observable.empty()) + } } diff --git a/RxSwift/Traits/PrimitiveSequence.swift b/RxSwift/Traits/PrimitiveSequence.swift index 740bce7d..398de9f2 100644 --- a/RxSwift/Traits/PrimitiveSequence.swift +++ b/RxSwift/Traits/PrimitiveSequence.swift @@ -8,7 +8,7 @@ /// Observable sequences containing 0 or 1 element. public struct PrimitiveSequence { - fileprivate let source: Observable + let source: Observable init(raw: Observable) { self.source = raw @@ -70,31 +70,6 @@ extension PrimitiveSequence { }) } - /** - Returns an observable sequence that contains a single element. - - - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) - - - parameter element: Single element in the resulting observable sequence. - - returns: An observable sequence containing the single specified element. - */ - public static func just(_ element: Element) -> PrimitiveSequence { - return PrimitiveSequence(raw: Observable.just(element)) - } - - /** - Returns an observable sequence that contains a single element. - - - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) - - - parameter element: Single element in the resulting observable sequence. - - parameter: Scheduler to send the single element on. - - returns: An observable sequence containing the single specified element. - */ - public static func just(_ element: Element, scheduler: ImmediateSchedulerType) -> PrimitiveSequence { - return PrimitiveSequence(raw: Observable.just(element, scheduler: scheduler)) - } - /** Returns an observable sequence that terminates with an `error`. @@ -132,84 +107,7 @@ extension PrimitiveSequence { return PrimitiveSequence(raw: source.delaySubscription(dueTime, scheduler: scheduler)) } - /** - Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. - - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) - - - parameter dueTime: Relative time shift of the source by. - - parameter scheduler: Scheduler to run the subscription delay timer on. - - returns: the source Observable shifted in time by the specified delay. - */ - public func delay(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.delay(dueTime, scheduler: scheduler)) - } - - /** - Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. - - - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) - - - parameter onNext: Action to invoke for each element in the observable sequence. - - parameter onError: Action to invoke upon errored termination of the observable sequence. - - parameter onCompleted: Action to invoke upon graceful termination of the observable sequence. - - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. - - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. - - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. - - returns: The source sequence with the side-effecting behavior applied. - */ - public func `do`(onNext: ((E) throws -> Void)? = nil, onError: ((Swift.Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> ())? = nil, onSubscribed: (() -> ())? = nil, onDispose: (() -> ())? = nil) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.do( - onNext: onNext, - onError: onError, - onCompleted: onCompleted, - onSubscribe: onSubscribe, - onSubscribed: onSubscribed, - onDispose: onDispose) - ) - } - - /** - Filters the elements of an observable sequence based on a predicate. - - - seealso: [filter operator on reactivex.io](http://reactivex.io/documentation/operators/filter.html) - - - parameter predicate: A function to test each source element for a condition. - - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. - */ - public func filter(_ predicate: @escaping (E) throws -> Bool) - -> Maybe { - return Maybe(raw: source.filter(predicate)) - } - - /** - Projects each element of an observable sequence into a new form. - - - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) - - - parameter transform: A transform function to apply to each source element. - - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. - - */ - public func map(_ transform: @escaping (E) throws -> R) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.map(transform)) - } - - /** - Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. - - - seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) - - - parameter selector: A transform function to apply to each element. - - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. - */ - public func flatMap(_ selector: @escaping (ElementType) throws -> PrimitiveSequence) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.flatMap(selector)) - } /** Wraps the source sequence in order to run its observer callbacks on the specified scheduler. @@ -333,34 +231,6 @@ extension PrimitiveSequence { })) } - /** - Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: An observable sequence with a `RxError.timeout` in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.timeout(dueTime, scheduler: scheduler)) - } - - /** - Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter other: Sequence to return in case of a timeout. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: The source sequence switching to the other sequence in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, other: PrimitiveSequence, scheduler: SchedulerType) - -> PrimitiveSequence { - return PrimitiveSequence(raw: source.timeout(dueTime, other: other.source, scheduler: scheduler)) - } } extension PrimitiveSequenceType where ElementType: SignedInteger @@ -380,121 +250,7 @@ extension PrimitiveSequenceType where ElementType: SignedInteger } } -extension PrimitiveSequenceType where TraitType == MaybeTrait { - /** - Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. - - seealso: [empty operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) - - - returns: An observable sequence with no elements. - */ - public static func empty() -> PrimitiveSequence { - return PrimitiveSequence(raw: Observable.empty()) - } -} - -extension PrimitiveSequenceType where TraitType == CompletableTrait, ElementType == Never { - /** - Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. - - - seealso: [empty operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html) - - - returns: An observable sequence with no elements. - */ - public static func empty() -> PrimitiveSequence { - return PrimitiveSequence(raw: Observable.empty()) - } - - /** - Concatenates the second observable sequence to `self` upon successful termination of `self`. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - parameter second: Second observable sequence. - - returns: An observable sequence that contains the elements of `self`, followed by those of the second sequence. - */ - public func concat(_ second: PrimitiveSequence) -> PrimitiveSequence { - return Completable.concat(primitiveSequence, second) - } - - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ sequence: S) -> PrimitiveSequence - where S.Iterator.Element == PrimitiveSequence { - let source = Observable.concat(sequence.lazy.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } - - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ collection: C) -> PrimitiveSequence - where C.Iterator.Element == PrimitiveSequence { - let source = Observable.concat(collection.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } - - /** - Concatenates all observable sequences in the given sequence, as long as the previous observable sequence terminated successfully. - - - seealso: [concat operator on reactivex.io](http://reactivex.io/documentation/operators/concat.html) - - - returns: An observable sequence that contains the elements of each given sequence, in sequential order. - */ - public static func concat(_ sources: PrimitiveSequence ...) -> PrimitiveSequence { - let source = Observable.concat(sources.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } - - /** - Merges elements from all observable sequences from collection into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: C) -> PrimitiveSequence - where C.Iterator.Element == PrimitiveSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } - - /** - Merges elements from all observable sequences from array into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Array of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: [PrimitiveSequence]) -> PrimitiveSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } - - /** - Merges elements from all observable sequences into a single observable sequence. - - - seealso: [merge operator on reactivex.io](http://reactivex.io/documentation/operators/merge.html) - - - parameter sources: Collection of observable sequences to merge. - - returns: The observable sequence that merges the elements of the observable sequences. - */ - public static func merge(_ sources: PrimitiveSequence...) -> PrimitiveSequence { - let source = Observable.merge(sources.map { $0.asObservable() }) - return PrimitiveSequence(raw: source) - } -} extension ObservableType { /** diff --git a/RxSwift/Traits/Single.swift b/RxSwift/Traits/Single.swift index 8ce0f6a1..4195e8b1 100644 --- a/RxSwift/Traits/Single.swift +++ b/RxSwift/Traits/Single.swift @@ -1,6 +1,6 @@ // // Single.swift -// Rx +// RxSwift // // Created by sergdort on 19/08/2017. // Copyright © 2017 Krunoslav Zaher. All rights reserved. @@ -30,7 +30,7 @@ extension PrimitiveSequenceType where TraitType == SingleTrait { - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method. - returns: The observable sequence with the specified implementation for the `subscribe` method. */ - public static func create(subscribe: @escaping (@escaping SingleObserver) -> Disposable) -> PrimitiveSequence { + public static func create(subscribe: @escaping (@escaping SingleObserver) -> Disposable) -> Single { let source = Observable.create { observer in return subscribe { event in switch event { @@ -86,4 +86,141 @@ extension PrimitiveSequenceType where TraitType == SingleTrait { } } } + + /** + Returns an observable sequence that contains a single element. + + - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) + + - parameter element: Single element in the resulting observable sequence. + - returns: An observable sequence containing the single specified element. + */ + public static func just(_ element: ElementType) -> Single { + return Single(raw: Observable.just(element)) + } + + /** + Returns an observable sequence that contains a single element. + + - seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html) + + - parameter element: Single element in the resulting observable sequence. + - parameter: Scheduler to send the single element on. + - returns: An observable sequence containing the single specified element. + */ + public static func just(_ element: ElementType, scheduler: ImmediateSchedulerType) -> Single { + return Single(raw: Observable.just(element, scheduler: scheduler)) + } + + /** + Returns an observable sequence by the source observable sequence shifted forward in time by a specified delay. Error events from the source observable sequence are not delayed. + + - seealso: [delay operator on reactivex.io](http://reactivex.io/documentation/operators/delay.html) + + - parameter dueTime: Relative time shift of the source by. + - parameter scheduler: Scheduler to run the subscription delay timer on. + - returns: the source Observable shifted in time by the specified delay. + */ + public func delay(_ dueTime: RxTimeInterval, scheduler: SchedulerType) + -> Single { + return Single(raw: primitiveSequence.source.delay(dueTime, scheduler: scheduler)) + } + + /** + Invokes an action for each event in the observable sequence, and propagates all observer messages through the result sequence. + + - seealso: [do operator on reactivex.io](http://reactivex.io/documentation/operators/do.html) + + - parameter onNext: Action to invoke for each element in the observable sequence. + - parameter onError: Action to invoke upon errored termination of the observable sequence. + - parameter onSubscribe: Action to invoke before subscribing to source observable sequence. + - parameter onSubscribed: Action to invoke after subscribing to source observable sequence. + - parameter onDispose: Action to invoke after subscription to source observable has been disposed for any reason. It can be either because sequence terminates for some reason or observer subscription being disposed. + - returns: The source sequence with the side-effecting behavior applied. + */ + public func `do`(onNext: ((ElementType) throws -> Void)? = nil, + onError: ((Swift.Error) throws -> Void)? = nil, + onSubscribe: (() -> ())? = nil, + onSubscribed: (() -> ())? = nil, + onDispose: (() -> ())? = nil) + -> Single { + return Single(raw: primitiveSequence.source.do( + onNext: onNext, + onError: onError, + onSubscribe: onSubscribe, + onSubscribed: onSubscribed, + onDispose: onDispose) + ) + } + + /** + Filters the elements of an observable sequence based on a predicate. + + - seealso: [filter operator on reactivex.io](http://reactivex.io/documentation/operators/filter.html) + + - parameter predicate: A function to test each source element for a condition. + - returns: An observable sequence that contains elements from the input sequence that satisfy the condition. + */ + public func filter(_ predicate: @escaping (ElementType) throws -> Bool) + -> Maybe { + return Maybe(raw: primitiveSequence.source.filter(predicate)) + } + + + /** + Projects each element of an observable sequence into a new form. + + - seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html) + + - parameter transform: A transform function to apply to each source element. + - returns: An observable sequence whose elements are the result of invoking the transform function on each element of source. + + */ + public func map(_ transform: @escaping (ElementType) throws -> R) + -> Single { + return Single(raw: primitiveSequence.source.map(transform)) + } + + /** + Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. + + - seealso: [flatMap operator on reactivex.io](http://reactivex.io/documentation/operators/flatmap.html) + + - parameter selector: A transform function to apply to each element. + - returns: An observable sequence whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. + */ + public func flatMap(_ selector: @escaping (ElementType) throws -> Single) + -> Single { + return Single(raw: primitiveSequence.source.flatMap(selector)) + } + + /** + Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: An observable sequence with a `RxError.timeout` in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) + -> Single { + return Single(raw: primitiveSequence.source.timeout(dueTime, scheduler: scheduler)) + } + + /** + Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter other: Sequence to return in case of a timeout. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: The source sequence switching to the other sequence in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, + other: Single, + scheduler: SchedulerType) -> Single { + return Single(raw: primitiveSequence.source.timeout(dueTime, other: other.source, scheduler: scheduler)) + } } From 072c20600dcbf5e5f202ed625236024463b53f06 Mon Sep 17 00:00:00 2001 From: sergdort Date: Mon, 21 Aug 2017 21:58:58 +0100 Subject: [PATCH 3/4] Add timeout operator on all traits --- RxSwift/Traits/Maybe.swift | 30 -------------------------- RxSwift/Traits/PrimitiveSequence.swift | 29 +++++++++++++++++++++++++ RxSwift/Traits/Single.swift | 30 -------------------------- 3 files changed, 29 insertions(+), 60 deletions(-) diff --git a/RxSwift/Traits/Maybe.swift b/RxSwift/Traits/Maybe.swift index 40d9a165..45232501 100644 --- a/RxSwift/Traits/Maybe.swift +++ b/RxSwift/Traits/Maybe.swift @@ -191,36 +191,6 @@ public extension PrimitiveSequenceType where TraitType == MaybeTrait { -> Maybe { return Maybe(raw: primitiveSequence.source.map(transform)) } - - /** - Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: An observable sequence with a `RxError.timeout` in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Maybe { - return Maybe(raw: primitiveSequence.source.timeout(dueTime, scheduler: scheduler)) - } - - /** - Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter other: Sequence to return in case of a timeout. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: The source sequence switching to the other sequence in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, - other: Maybe, - scheduler: SchedulerType) -> Maybe { - return Maybe(raw: primitiveSequence.source.timeout(dueTime, other: other.source, scheduler: scheduler)) - } /** Returns an empty observable sequence, using the specified scheduler to send out the single `Completed` message. diff --git a/RxSwift/Traits/PrimitiveSequence.swift b/RxSwift/Traits/PrimitiveSequence.swift index 398de9f2..798caad0 100644 --- a/RxSwift/Traits/PrimitiveSequence.swift +++ b/RxSwift/Traits/PrimitiveSequence.swift @@ -231,6 +231,35 @@ extension PrimitiveSequence { })) } + /** + Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: An observable sequence with a `RxError.timeout` in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) + -> PrimitiveSequence { + return PrimitiveSequence(raw: primitiveSequence.source.timeout(dueTime, scheduler: scheduler)) + } + + /** + Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. + + - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) + + - parameter dueTime: Maximum duration between values before a timeout occurs. + - parameter other: Sequence to return in case of a timeout. + - parameter scheduler: Scheduler to run the timeout timer on. + - returns: The source sequence switching to the other sequence in case of a timeout. + */ + public func timeout(_ dueTime: RxTimeInterval, + other: PrimitiveSequence, + scheduler: SchedulerType) -> PrimitiveSequence { + return PrimitiveSequence(raw: primitiveSequence.source.timeout(dueTime, other: other.source, scheduler: scheduler)) + } } extension PrimitiveSequenceType where ElementType: SignedInteger diff --git a/RxSwift/Traits/Single.swift b/RxSwift/Traits/Single.swift index 4195e8b1..caec64c3 100644 --- a/RxSwift/Traits/Single.swift +++ b/RxSwift/Traits/Single.swift @@ -193,34 +193,4 @@ extension PrimitiveSequenceType where TraitType == SingleTrait { -> Single { return Single(raw: primitiveSequence.source.flatMap(selector)) } - - /** - Applies a timeout policy for each element in the observable sequence. If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutError is propagated to the observer. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: An observable sequence with a `RxError.timeout` in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, scheduler: SchedulerType) - -> Single { - return Single(raw: primitiveSequence.source.timeout(dueTime, scheduler: scheduler)) - } - - /** - Applies a timeout policy for each element in the observable sequence, using the specified scheduler to run timeout timers. If the next element isn't received within the specified timeout duration starting from its predecessor, the other observable sequence is used to produce future messages from that point on. - - - seealso: [timeout operator on reactivex.io](http://reactivex.io/documentation/operators/timeout.html) - - - parameter dueTime: Maximum duration between values before a timeout occurs. - - parameter other: Sequence to return in case of a timeout. - - parameter scheduler: Scheduler to run the timeout timer on. - - returns: The source sequence switching to the other sequence in case of a timeout. - */ - public func timeout(_ dueTime: RxTimeInterval, - other: Single, - scheduler: SchedulerType) -> Single { - return Single(raw: primitiveSequence.source.timeout(dueTime, other: other.source, scheduler: scheduler)) - } } From 3610ee2e36b28f4b1d2150f1540cead263c658ad Mon Sep 17 00:00:00 2001 From: sergdort Date: Mon, 28 Aug 2017 16:05:37 +0100 Subject: [PATCH 4/4] run ./scripts/package-spm.swift --- Sources/RxSwift/Completable.swift | 1 + Sources/RxSwift/Maybe.swift | 1 + Sources/RxSwift/Single.swift | 1 + 3 files changed, 3 insertions(+) create mode 120000 Sources/RxSwift/Completable.swift create mode 120000 Sources/RxSwift/Maybe.swift create mode 120000 Sources/RxSwift/Single.swift diff --git a/Sources/RxSwift/Completable.swift b/Sources/RxSwift/Completable.swift new file mode 120000 index 00000000..190de79e --- /dev/null +++ b/Sources/RxSwift/Completable.swift @@ -0,0 +1 @@ +../../RxSwift/Traits/Completable.swift \ No newline at end of file diff --git a/Sources/RxSwift/Maybe.swift b/Sources/RxSwift/Maybe.swift new file mode 120000 index 00000000..80352b43 --- /dev/null +++ b/Sources/RxSwift/Maybe.swift @@ -0,0 +1 @@ +../../RxSwift/Traits/Maybe.swift \ No newline at end of file diff --git a/Sources/RxSwift/Single.swift b/Sources/RxSwift/Single.swift new file mode 120000 index 00000000..383f19b6 --- /dev/null +++ b/Sources/RxSwift/Single.swift @@ -0,0 +1 @@ +../../RxSwift/Traits/Single.swift \ No newline at end of file