Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variadic sugar for boolean static methods. #801

Merged
merged 4 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
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 @@ -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<Bool, Never> { observer, _ in
observer.send(value: false)
observer.sendCompleted()
Expand All @@ -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())
}
}
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