Skip to content

Commit

Permalink
Add variadic sugar for boolean static methods. (#801)
Browse files Browse the repository at this point in the history
* Add variadic sugar for boolean static methods.

* Fix typo.

* Edit changelog.

Co-authored-by: Anders Ha <anders@andersha.com>
  • Loading branch information
fortmarek and andersio committed Oct 27, 2020
1 parent 2d46703 commit aac1d75
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,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`.
Expand Down
20 changes: 20 additions & 0 deletions Sources/Property.swift
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,16 @@ extension PropertyProtocol where Value == Bool {
public static func all<P: PropertyProtocol, Properties: Collection>(_ properties: Properties) -> Property<Value> 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<P: PropertyProtocol>(_ properties: P...) -> Property<Value> where P.Value == Value {
return .all(properties)
}

/// Create a property that computes a logical OR between the latest values of `self`
/// and `property`.
Expand All @@ -464,6 +474,16 @@ extension PropertyProtocol where Value == Bool {
public static func any<P: PropertyProtocol, Properties: Collection>(_ properties: Properties) -> Property<Value> 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<P: PropertyProtocol>(_ properties: P...) -> Property<Value> where P.Value == Value {
return .any(properties)
}
}

/// A read-only property that can be observed for its changes over time. There
Expand Down
22 changes: 21 additions & 1 deletion Sources/Signal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2210,6 +2210,16 @@ extension Signal where Value == Bool {
public static func all<BooleansCollection: Collection>(_ booleans: BooleansCollection) -> Signal<Value, Error> where BooleansCollection.Element == Signal<Value, Error> {
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<Value, Error>...) -> Signal<Value, Error> {
return .all(booleans)
}

/// Create a signal that computes a logical OR between the latest values of `self`
/// and `signal`.
Expand All @@ -2230,7 +2240,17 @@ extension Signal where Value == Bool {
/// - returns: A signal that emits the logical OR results.
public static func any<BooleansCollection: Collection>(_ booleans: BooleansCollection) -> Signal<Value, Error> where BooleansCollection.Element == Signal<Value, Error> {
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<Value, Error>...) -> Signal<Value, Error> {
return .any(booleans)
}
}

extension Signal {
Expand Down
24 changes: 24 additions & 0 deletions Sources/SignalProducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2770,6 +2770,18 @@ extension SignalProducer where Value == Bool {
public static func all<BooleansCollection: Collection>(_ booleans: BooleansCollection) -> SignalProducer<Value, Error> where BooleansCollection.Element == SignalProducer<Value, Error> {
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<Value, Error>...) -> SignalProducer<Value, Error> {
return .all(booleans)
}

/// Create a producer that computes a logical AND between the latest values of `booleans`.
///
Expand Down Expand Up @@ -2816,6 +2828,18 @@ extension SignalProducer where Value == Bool {
public static func any<BooleansCollection: Collection>(_ booleans: BooleansCollection) -> SignalProducer<Value, Error> where BooleansCollection.Element == SignalProducer<Value, Error> {
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<Value, Error>...) -> SignalProducer<Value, Error> {
return .any(booleans)
}

/// Create a producer that computes a logical OR between the latest values of `booleans`.
///
Expand Down
4 changes: 2 additions & 2 deletions Tests/ReactiveSwiftTests/PropertySpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
4 changes: 2 additions & 2 deletions Tests/ReactiveSwiftTests/SignalProducerSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3692,7 +3692,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<Bool, Never> { observer, _ in
observer.send(value: false)
observer.sendCompleted()
Expand All @@ -3706,7 +3706,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())
}
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/ReactiveSwiftTests/SignalSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Bool, Never>.pipe()
let (signal2, observer2) = Signal<Bool, Never>.pipe()
let (signal3, observer3) = Signal<Bool, Never>.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)
Expand Down

0 comments on commit aac1d75

Please sign in to comment.