diff --git a/CHANGELOG.md b/CHANGELOG.md index 0541e1c30..60aaf9b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ # 6.4.0 1. Bump min. deployment target to iOS 9 when using swift packages to silence Xcode 12 warnings. Update Quick & Nibmle to the latest version when using swift packages. +1. Add variadic sugar for boolean static methods such as `Property.any(boolProperty1, boolProperty2, boolProperty3)` (#801, kudos to @fortmarek) 1. Fix a debug assertion in `Lock.try()` that could be raised in earlier OS versions (< iOS 10.0, < macOS 10.12). (#747, #788) Specifically, ReactiveSwift now recognizes `EDEADLK` as expected error code from `pthread_mutex_trylock` alongside `0`, `EBUSY` and `EAGAIN`. diff --git a/Sources/Property.swift b/Sources/Property.swift index 9552b9595..00e8e12a8 100644 --- a/Sources/Property.swift +++ b/Sources/Property.swift @@ -443,6 +443,16 @@ extension PropertyProtocol where Value == Bool { public static func all(_ properties: Properties) -> Property where P.Value == Value, Properties.Element == P { return Property(initial: properties.map { $0.value }.reduce(true) { $0 && $1 }, then: SignalProducer.all(properties)) } + + /// Create a property that computes a logical AND between the latest values of `properties`. + /// + /// - parameters: + /// - property: Properties to be combined. + /// + /// - returns: A property that contains the logical AND results. + public static func all(_ properties: P...) -> Property where P.Value == Value { + return .all(properties) + } /// Create a property that computes a logical OR between the latest values of `self` /// and `property`. @@ -464,6 +474,16 @@ extension PropertyProtocol where Value == Bool { public static func any(_ properties: Properties) -> Property where P.Value == Value, Properties.Element == P { return Property(initial: properties.map { $0.value }.reduce(false) { $0 || $1 }, then: SignalProducer.any(properties)) } + + /// Create a property that computes a logical OR between the latest values of `properties`. + /// + /// - parameters: + /// - properties: Properties to be combined. + /// + /// - returns: A property that contains the logical OR results. + public static func any(_ properties: P...) -> Property where P.Value == Value { + return .any(properties) + } } /// A read-only property that can be observed for its changes over time. There diff --git a/Sources/Signal.swift b/Sources/Signal.swift index f2d4fb471..4bb6238aa 100644 --- a/Sources/Signal.swift +++ b/Sources/Signal.swift @@ -2210,6 +2210,16 @@ extension Signal where Value == Bool { public static func all(_ booleans: BooleansCollection) -> Signal where BooleansCollection.Element == Signal { return combineLatest(booleans).map { $0.reduce(true) { $0 && $1 } } } + + /// Create a signal that computes a logical AND between the latest values of `booleans`. + /// + /// - parameters: + /// - booleans: Boolean signals to be combined. + /// + /// - returns: A signal that emits the logical AND results. + public static func all(_ booleans: Signal...) -> Signal { + return .all(booleans) + } /// Create a signal that computes a logical OR between the latest values of `self` /// and `signal`. @@ -2230,7 +2240,17 @@ extension Signal where Value == Bool { /// - returns: A signal that emits the logical OR results. public static func any(_ booleans: BooleansCollection) -> Signal where BooleansCollection.Element == Signal { return combineLatest(booleans).map { $0.reduce(false) { $0 || $1 } } - } + } + + /// Create a signal that computes a logical OR between the latest values of `booleans`. + /// + /// - parameters: + /// - booleans: Boolean signals to be combined. + /// + /// - returns: A signal that emits the logical OR results. + public static func any(_ booleans: Signal...) -> Signal { + return .any(booleans) + } } extension Signal { diff --git a/Sources/SignalProducer.swift b/Sources/SignalProducer.swift index 36efdaa59..e2678140e 100644 --- a/Sources/SignalProducer.swift +++ b/Sources/SignalProducer.swift @@ -2770,6 +2770,18 @@ extension SignalProducer where Value == Bool { public static func all(_ booleans: BooleansCollection) -> SignalProducer where BooleansCollection.Element == SignalProducer { return combineLatest(booleans, emptySentinel: []).map { $0.reduce(true) { $0 && $1 } } } + + /// Create a producer that computes a logical AND between the latest values of `booleans`. + /// + /// If no producer is given in `booleans`, the resulting producer constantly emits `true`. + /// + /// - parameters: + /// - booleans: Boolean producers to be combined. + /// + /// - returns: A producer that emits the logical AND results. + public static func all(_ booleans: SignalProducer...) -> SignalProducer { + return .all(booleans) + } /// Create a producer that computes a logical AND between the latest values of `booleans`. /// @@ -2816,6 +2828,18 @@ extension SignalProducer where Value == Bool { public static func any(_ booleans: BooleansCollection) -> SignalProducer where BooleansCollection.Element == SignalProducer { return combineLatest(booleans, emptySentinel: []).map { $0.reduce(false) { $0 || $1 } } } + + /// Create a producer that computes a logical OR between the latest values of `booleans`. + /// + /// If no producer is given in `booleans`, the resulting producer constantly emits `false`. + /// + /// - parameters: + /// - booleans: Boolean producers to be combined. + /// + /// - returns: A producer that emits the logical OR results. + public static func any(_ booleans: SignalProducer...) -> SignalProducer { + return .any(booleans) + } /// Create a producer that computes a logical OR between the latest values of `booleans`. /// diff --git a/Tests/ReactiveSwiftTests/PropertySpec.swift b/Tests/ReactiveSwiftTests/PropertySpec.swift index 235cb782a..ba6af040c 100644 --- a/Tests/ReactiveSwiftTests/PropertySpec.swift +++ b/Tests/ReactiveSwiftTests/PropertySpec.swift @@ -1789,11 +1789,11 @@ class PropertySpec: QuickSpec { expect(Property.any([property1, property2, property3]).value).to(beTrue()) } - it("should emit false when all properties in array contain false") { + it("should emit false when all properties contain false") { let property1 = MutableProperty(false) let property2 = MutableProperty(false) let property3 = MutableProperty(false) - expect(Property.any([property1, property2, property3]).value).to(beFalse()) + expect(Property.any(property1, property2, property3).value).to(beFalse()) } it("should emit false when array of properties is empty") { diff --git a/Tests/ReactiveSwiftTests/SignalProducerSpec.swift b/Tests/ReactiveSwiftTests/SignalProducerSpec.swift index 0f41f0ef0..a339a26e5 100644 --- a/Tests/ReactiveSwiftTests/SignalProducerSpec.swift +++ b/Tests/ReactiveSwiftTests/SignalProducerSpec.swift @@ -3623,7 +3623,7 @@ class SignalProducerSpec: QuickSpec { } } - it("should emit false when all producers in array emit false") { + it("should emit false when all producers emit false") { let producer1 = SignalProducer { observer, _ in observer.send(value: false) observer.sendCompleted() @@ -3637,7 +3637,7 @@ class SignalProducerSpec: QuickSpec { observer.sendCompleted() } - SignalProducer.any([producer1, producer2, producer3]).startWithValues { value in + SignalProducer.any(producer1, producer2, producer3).startWithValues { value in expect(value).to(beFalse()) } } diff --git a/Tests/ReactiveSwiftTests/SignalSpec.swift b/Tests/ReactiveSwiftTests/SignalSpec.swift index bd50b5fe0..2fe7f6841 100755 --- a/Tests/ReactiveSwiftTests/SignalSpec.swift +++ b/Tests/ReactiveSwiftTests/SignalSpec.swift @@ -3896,11 +3896,11 @@ class SignalSpec: QuickSpec { observer3.sendCompleted() } - it("should emit false when all signals in array emits false") { + it("should emit false when all signals emits false") { let (signal1, observer1) = Signal.pipe() let (signal2, observer2) = Signal.pipe() let (signal3, observer3) = Signal.pipe() - Signal.any([signal1, signal2, signal3]).observeValues { value in + Signal.any(signal1, signal2, signal3).observeValues { value in expect(value).to(beFalse()) } observer1.send(value: false)