/*:#localized(key: "SuspendThenResume")
 # `withCheckedContinuation`: suspend, then resume

 Let's bridge a real-feeling legacy API. Imagine an older corner-coffee-bar
 SDK that fetches today's special the old way: a completion handler,
 delivered after a delay from a background queue. You can't change it; you
 just want to `await` it.
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

// --- The legacy API you're stuck with (completion handler) ---
func fetchTodaysSpecial(completion: @escaping @Sendable (String) -> Void) {
    // Simulates a slow lookup that calls back later, off the main thread.
    DispatchQueue.global().asyncAfter(deadline: .now() + 0.4) {
        completion("Oat-milk cortado")
    }
}

// --- Your modern async wrapper ---
func todaysSpecial() async -> String {
    await withCheckedContinuation { continuation in
        fetchTodaysSpecial { special in
            continuation.resume(returning: special)
        }
    }
}

Task {
    print("Asking the counter for today's special...")
    let special = await todaysSpecial()
    print("Today's special: \(special)")
    PlaygroundPage.current.finishExecution()
}
//#-end-editable-code
/*:#localized(key: "SuspendThenResume-2")
 **Watch it run:** `Asking the counter...` prints first. Then the page pauses
 for about four-tenths of a second: that's `todaysSpecial()` **suspended** at
 its `await`, waiting on the continuation. When `fetchTodaysSpecial`'s
 completion fires, `resume(returning:)` delivers the string, the async
 function wakes up, and the special prints. You wrapped a callback in `await`
 without touching the old API.

 * callout(Try it): Change the `asyncAfter` delay to `1.5`. The "Asking the
 counter..." line still prints first, and the pause before the special just
 gets longer.

 > **Why `@Sendable` on the completion?** The legacy API hops
 > to a background queue, and in Swift 6 a closure that crosses that boundary
 > must be `@Sendable` (safe to hand to another thread). It's on the
 > *simulated* API here so the example stays warning-clean; real SDK completion
 > handlers you're bridging usually already carry it. Sendable gets its own
 > treatment in the chapter [Global Actors and Sendable](Global%20Actors%20and%20Sendable.playgroundchapter/Overview).

 [Previous](@previous)  |  page 2 of 8  |  [Next: Failing with a Result](@next)
 */
