Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active March 25, 2022 15:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielt1263/69697d3bee26f960fa853f835b10335b to your computer and use it in GitHub Desktop.
Save danielt1263/69697d3bee26f960fa853f835b10335b to your computer and use it in GitHub Desktop.
//
// PublisherResultTransforms.swift
// rx-sandbox
//
// Created by Daniel Tartaglia on 9/19/21.
//
import Combine
/**
All of the methods below assume that you have an `Publisher<Result<Input, Failure>, Never>` and want to transform it into an
`Publisher<Result<Output, Failure>, Never>` through some means.
*/
extension Publisher where Failure == Never {
/// - parameter transform: `(Input) -> Output`
public func mapResult<Input, Output, Failure>(_ transform: @escaping (Input) -> Output) -> some Publisher where Self.Output == Result<Input, Failure> {
map { $0.map(transform) }
}
/// - parameter transform: `(Input) throws -> Output`
public func mapResult<Input, Output, Failure>(_ transform: @escaping (Input) throws -> Output) -> some Publisher where Self.Output == Result<Input, Failure> {
map { $0.map { value in Result { try transform(value) } } }
}
/// - parameter transform: `(Input) -> Result<Output, Failure>`
public func mapResult<Input, Output, Failure>( _ transform: @escaping (Input) -> Result<Output, Failure>) -> some Publisher where Self.Output == Result<Input, Failure> {
return map { $0.flatMap(transform) }
}
/// - parameter transform: `(Input) -> AnyPublisher<Output, Failure>`.
public func flatMapResult<Input, Output, Failure>(_ transform: @escaping (Input) -> AnyPublisher<Output, Failure>) -> some Publisher where Self.Output == Result<Input, Failure> {
flatMap { (result) -> AnyPublisher<Result<Output, Failure>, Never> in
switch result {
case let .success(value):
return transform(value)
.map(Result.success)
.catch { Just(Result.failure($0)) }
.eraseToAnyPublisher()
case let .failure(error):
return Just(Result.failure(error))
.eraseToAnyPublisher()
}
}
}
/// - parameter transform: `(Input) -> AnyPublisher<Result<Output, Failure>, Never>`.
public func flatMapResult<Input, Output, Failure>(_ transform: @escaping (Input) -> AnyPublisher<Result<Output, Failure>, Never>) -> some Publisher where Self.Output == Result<Input, Failure> {
flatMap { result -> AnyPublisher<Result<Output, Failure>, Never> in
switch result.map(transform) {
case .success(let value):
return value
case .failure(let error):
return Just(Result.failure(error))
.eraseToAnyPublisher()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment