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

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. //
  2. // and.swift
  3. // RxSwiftExt
  4. //
  5. // Created by Florent Pillet on 26/11/17.
  6. // Copyright © 2017 RxSwift Community. All rights reserved.
  7. //
  8. import Foundation
  9. import RxSwift
  10. extension ObservableType where Element == Bool {
  11. /**
  12. Emits a single Bool value indicating whether or not a Bool sequence emits only `true` values.
  13. If a `false` value is emitted, the resulting sequence immediately completes with a `false` result.
  14. If only `true` values are emitted, the resulting sequence completes with a `true` result once the
  15. source sequence completes.
  16. If no value is emitted, the resulting sequence completes with no value once the source sequence completes.
  17. Use `asSingle()` or `asObservable()` to convert to your requirements.
  18. */
  19. public func and() -> Maybe<Element> {
  20. return Maybe.create { observer in
  21. var gotValue = false
  22. return self.subscribe { event in
  23. switch event {
  24. case .next(let value):
  25. if !value {
  26. // first `false` value emits false & completes
  27. observer(.success(false))
  28. } else {
  29. gotValue = true
  30. }
  31. case .error(let error):
  32. observer(.error(error))
  33. case .completed:
  34. observer(gotValue ? .success(true) : .completed)
  35. }
  36. }
  37. }
  38. }
  39. /**
  40. Emits a single Bool value indicating whether or not a each Bool sequence in the collection emits only `true` values.
  41. Each sequence of the collection is expected to emit at least one `true` value.
  42. If any sequence does not emit anything, the produced `Maybe` will just complete.
  43. If any sequence emits a `false` value, the produiced `Maybe` will emit a `false` result.
  44. If all sequences emit at least one `true` value, the produced `Maybe` will emit a `true` result.
  45. Use `asSingle()` or `asObservable()` to convert to your requirements.
  46. */
  47. public static func and<Collection: Swift.Collection>(_ collection: Collection)
  48. -> Maybe<Element> where Collection.Element: ObservableType, Collection.Element.Element == Element {
  49. return Maybe.create { observer in
  50. var emitted = [Bool](repeating: false, count: Int(collection.count))
  51. var completed = 0
  52. let lock = NSRecursiveLock()
  53. lock.lock()
  54. defer { lock.unlock() }
  55. let subscriptions = collection.enumerated().map { item in
  56. item.element.subscribe { event in
  57. lock.lock()
  58. defer { lock.unlock() }
  59. switch event {
  60. case .next(let value):
  61. if !value {
  62. // first `false` value emits false & completes
  63. observer(.success(false))
  64. } else {
  65. emitted[item.offset] = true
  66. }
  67. case .error(let error):
  68. observer(.error(error))
  69. case .completed:
  70. completed += 1
  71. guard completed == collection.count else { return }
  72. // if all emitted at least one `true`, emit true otherwise just complete
  73. if emitted.allSatisfy({ $0 }) {
  74. observer(.success(true))
  75. } else {
  76. observer(.completed)
  77. }
  78. }
  79. }
  80. }
  81. return CompositeDisposable(disposables: subscriptions)
  82. }
  83. }
  84. /**
  85. Emits a single Bool value indicating whether or not a each Bool sequence in the collection emits only `true` values.
  86. Each sequence of the collection is expected to emit at least one `true` value.
  87. If any sequence does not emit anything, the produced `Maybe` will just complete.
  88. If any sequence emits a `false` value, the produiced `Maybe` will emit a `false` result.
  89. If all sequences emit at least one `true` value, the produced `Maybe` will emit a `true` result.
  90. Use `asSingle()` or `asObservable()` to convert to your requirements.
  91. */
  92. public static func and<Observable: ObservableType>(_ sources: Observable ...) -> Maybe<Element> where Observable.Element == Element {
  93. return and(sources)
  94. }
  95. }