You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.6 KiB
106 lines
3.6 KiB
//
|
|
// and.swift
|
|
// RxSwiftExt
|
|
//
|
|
// Created by Florent Pillet on 26/11/17.
|
|
// Copyright © 2017 RxSwift Community. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import RxSwift
|
|
|
|
extension ObservableType where Element == Bool {
|
|
/**
|
|
Emits a single Bool value indicating whether or not a Bool sequence emits only `true` values.
|
|
|
|
If a `false` value is emitted, the resulting sequence immediately completes with a `false` result.
|
|
If only `true` values are emitted, the resulting sequence completes with a `true` result once the
|
|
source sequence completes.
|
|
If no value is emitted, the resulting sequence completes with no value once the source sequence completes.
|
|
|
|
Use `asSingle()` or `asObservable()` to convert to your requirements.
|
|
*/
|
|
public func and() -> Maybe<Element> {
|
|
return Maybe.create { observer in
|
|
var gotValue = false
|
|
return self.subscribe { event in
|
|
switch event {
|
|
case .next(let value):
|
|
if !value {
|
|
// first `false` value emits false & completes
|
|
observer(.success(false))
|
|
} else {
|
|
gotValue = true
|
|
}
|
|
case .error(let error):
|
|
observer(.error(error))
|
|
case .completed:
|
|
observer(gotValue ? .success(true) : .completed)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Emits a single Bool value indicating whether or not a each Bool sequence in the collection emits only `true` values.
|
|
|
|
Each sequence of the collection is expected to emit at least one `true` value.
|
|
If any sequence does not emit anything, the produced `Maybe` will just complete.
|
|
If any sequence emits a `false` value, the produiced `Maybe` will emit a `false` result.
|
|
If all sequences emit at least one `true` value, the produced `Maybe` will emit a `true` result.
|
|
|
|
Use `asSingle()` or `asObservable()` to convert to your requirements.
|
|
*/
|
|
public static func and<Collection: Swift.Collection>(_ collection: Collection)
|
|
-> Maybe<Element> where Collection.Element: ObservableType, Collection.Element.Element == Element {
|
|
return Maybe.create { observer in
|
|
var emitted = [Bool](repeating: false, count: Int(collection.count))
|
|
var completed = 0
|
|
let lock = NSRecursiveLock()
|
|
lock.lock()
|
|
defer { lock.unlock() }
|
|
let subscriptions = collection.enumerated().map { item in
|
|
item.element.subscribe { event in
|
|
lock.lock()
|
|
defer { lock.unlock() }
|
|
switch event {
|
|
case .next(let value):
|
|
if !value {
|
|
// first `false` value emits false & completes
|
|
observer(.success(false))
|
|
} else {
|
|
emitted[item.offset] = true
|
|
}
|
|
case .error(let error):
|
|
observer(.error(error))
|
|
case .completed:
|
|
completed += 1
|
|
guard completed == collection.count else { return }
|
|
// if all emitted at least one `true`, emit true otherwise just complete
|
|
if emitted.allSatisfy({ $0 }) {
|
|
observer(.success(true))
|
|
} else {
|
|
observer(.completed)
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return CompositeDisposable(disposables: subscriptions)
|
|
}
|
|
}
|
|
|
|
/**
|
|
Emits a single Bool value indicating whether or not a each Bool sequence in the collection emits only `true` values.
|
|
|
|
Each sequence of the collection is expected to emit at least one `true` value.
|
|
If any sequence does not emit anything, the produced `Maybe` will just complete.
|
|
If any sequence emits a `false` value, the produiced `Maybe` will emit a `false` result.
|
|
If all sequences emit at least one `true` value, the produced `Maybe` will emit a `true` result.
|
|
|
|
Use `asSingle()` or `asObservable()` to convert to your requirements.
|
|
*/
|
|
public static func and<Observable: ObservableType>(_ sources: Observable ...) -> Maybe<Element> where Observable.Element == Element {
|
|
return and(sources)
|
|
}
|
|
}
|