Skip to content

Instantly share code, notes, and snippets.

@rpassis
Created July 3, 2019 14:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rpassis/146149e07bbde0d30599270c2766f805 to your computer and use it in GitHub Desktop.
Save rpassis/146149e07bbde0d30599270c2766f805 to your computer and use it in GitHub Desktop.
Combine Recipe - Unwrapping an optional type operator
public protocol OptionalType {
associatedtype Wrapped
var value: Wrapped? { get }
}
extension Optional: OptionalType {
public var value: Wrapped? {
return self
}
}
extension Publishers {
struct Unwrapped<Upstream> : Publisher where Upstream: Publisher, Upstream.Output: OptionalType {
public typealias Output = Upstream.Output.Wrapped
public typealias Failure = Upstream.Failure
/// The publisher from which this publisher receives elements.
public let upstream: AnyPublisher<Upstream.Output.Wrapped, Upstream.Failure>
public init(upstream: Upstream) {
self.upstream = upstream
.flatMap { optional -> AnyPublisher<Output, Failure> in
guard let unwrapped = optional.value else {
return Publishers.Empty().eraseToAnyPublisher()
}
return Publishers.Once(unwrapped).eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
public func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
upstream.receive(subscriber: subscriber)
}
}
}
extension Publisher where Output: OptionalType {
func unwrap() -> Publishers.Unwrapped<Self> {
return Publishers.Unwrapped(upstream: self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment