Search code examples
swiftcombine

Making custom Deffered Future Publisher in Swift Combine?


Like the title says I would like to make custom publisher that will basically function like deffered future. Normally when I want to encapsulate code in some Future, but want it to execute on subscription, I would need to write something like this:

Deffered {
    Future { promise in
    }
}

Now I was thinking of making custom publisher, something along the lines DefferedFuture that will have exact same functionality as Future, but will execute promise only on subscription?


Solution

  • The most obvious answer is this:

    func single<Output, Failure>(_ promise: @escaping (@escaping (Result<Output, Failure>) -> Void) -> Void) -> Deferred<Future<Output, Failure>> where Failure: Error {
        Deferred {
            Future<Output, Failure>(promise)
        }
    }
    

    If it absolutely must be a type rather than a function then:

    extension Publishers {
        struct Single<Output, Failure>: Publisher where Failure: Error {
            let promise: (@escaping (Result<Output, Failure>) -> Void) -> Void
            
            func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
                Deferred { Future(promise) }
                .subscribe(subscriber)
            }
        }
    }