[Xcode 12] Add new flatMap(maxPublishers:_:) overloads

This commit is contained in:
Sergej Jaskiewicz
2020-10-28 22:02:21 +03:00
committed by Sergej Jaskiewicz
parent 9d87a3b4ea
commit efb4369c74
2 changed files with 91 additions and 1 deletions
@@ -56,7 +56,7 @@ extension Publisher {
/// subscriptions, or `Subscribers.Demand.unlimited` if unspecified.
/// - transform: A closure that takes an element as a parameter and returns
/// a publisher that produces elements of that type.
/// - Returns: A publisher that transforms elements from an upstream publisher into
/// - Returns: A publisher that transforms elements from an upstream publisher into
/// a publisher of that elements type.
public func flatMap<Result, Child: Publisher>(
maxPublishers: Subscribers.Demand = .unlimited,
@@ -69,6 +69,68 @@ extension Publisher {
}
}
extension Publisher where Failure == Never {
/// Transforms all elements from an upstream publisher into a new publisher up to
/// a maximum number of publishers you specify.
///
/// - Parameters:
/// - maxPublishers: Specifies the maximum number of concurrent publisher
/// subscriptions, or `Subscribers.Demand.unlimited` if unspecified.
/// - transform: A closure that takes an element as a parameter and returns
/// a publisher that produces elements of that type.
/// - Returns: A publisher that transforms elements from an upstream publisher into
/// a publisher of that elements type.
public func flatMap<Child: Publisher>(
maxPublishers: Subscribers.Demand = .unlimited,
_ transform: @escaping (Output) -> Child
) -> Publishers.FlatMap<Child, Publishers.SetFailureType<Self, Child.Failure>> {
return setFailureType(to: Child.Failure.self)
.flatMap(maxPublishers: maxPublishers, transform)
}
/// Transforms all elements from an upstream publisher into a new publisher up to
/// a maximum number of publishers you specify.
///
/// - Parameters:
/// - maxPublishers: Specifies the maximum number of concurrent publisher
/// subscriptions, or `Subscribers.Demand.unlimited` if unspecified.
/// - transform: A closure that takes an element as a parameter and returns
/// a publisher that produces elements of that type.
/// - Returns: A publisher that transforms elements from an upstream publisher
/// into a publisher of that elements type.
public func flatMap<Child: Publisher>(
maxPublishers: Subscribers.Demand = .unlimited,
_ transform: @escaping (Output) -> Child
) -> Publishers.FlatMap<Child, Self> where Child.Failure == Never {
return .init(upstream: self, maxPublishers: maxPublishers, transform: transform)
}
}
extension Publisher {
/// Transforms all elements from an upstream publisher into a new publisher up to
/// a maximum number of publishers you specify.
///
/// - Parameters:
/// - maxPublishers: Specifies the maximum number of concurrent publisher
/// subscriptions, or `Subscribers.Demand.unlimited` if unspecified.
/// - transform: A closure that takes an element as a parameter and returns
/// a publisher that produces elements of that type.
/// - Returns: A publisher that transforms elements from an upstream publisher into
/// a publisher of that elements type.
public func flatMap<Child: Publisher>(
maxPublishers: Subscribers.Demand = .unlimited,
_ transform: @escaping (Output) -> Child
) -> Publishers.FlatMap<Publishers.SetFailureType<Child, Failure>, Self>
where Child.Failure == Never
{
return flatMap(maxPublishers: maxPublishers) {
transform($0).setFailureType(to: Failure.self)
}
}
}
extension Publishers {
/// A publisher that transforms elements from an upstream publisher into a new
@@ -1043,6 +1043,34 @@ final class FlatMapTests: XCTestCase {
)
}
func testOverloadWhenUpstreamNeverFailsButChildrenCanFail() {
let child = CustomPublisher(subscription: nil)
let helper = OperatorTestHelper(
publisherType: CustomPublisherBase<Int, Never>.self,
initialDemand: .max(1),
receiveValueDemand: .max(100),
createSut: { $0.flatMap { _ in child } }
)
XCTAssertEqual(helper.sut.upstream.upstream, helper.publisher)
XCTAssertEqual(helper.sut.transform(0), child)
}
func testOverloadWhenUpstreamCanFailButChildrenNeverFail() {
let child = CustomPublisherBase<Int, Never>(subscription: nil)
let helper = OperatorTestHelper(
publisherType: CustomPublisherBase<Int,
TestingError>.self,
initialDemand: .max(1),
receiveValueDemand: .max(100),
createSut: { $0.flatMap { _ in child } }
)
XCTAssertEqual(helper.sut.upstream, helper.publisher)
XCTAssertEqual(helper.sut.transform(0).upstream, child)
}
func testFlatMapReflection() throws {
try testReflection(parentInput: String.self,
parentFailure: Never.self,