punchnet-macos/Tun/Concurrency/AsyncPromise.swift
2026-05-27 19:47:44 +08:00

54 lines
1.2 KiB
Swift

//
// AsyncPromise.swift
// punchnet
//
// Created by on 2026/5/27.
//
import Foundation
public actor AsyncPromise<Value: Sendable> {
private enum State {
case pending([CheckedContinuation<Value, Error>])
case completed(Result<Value, Error>)
}
private var state: State = .pending([])
public init() {
}
public func value() async throws -> Value {
try await withCheckedThrowingContinuation { continuation in
switch state {
case .pending(var continuations):
continuations.append(continuation)
state = .pending(continuations)
case .completed(let result):
continuation.resume(with: result)
}
}
}
public func succeed(_ value: Value) {
complete(.success(value))
}
public func fail(_ error: Error) {
complete(.failure(error))
}
private func complete(_ result: Result<Value, Error>) {
guard case .pending(let continuations) = state else {
return
}
state = .completed(result)
for continuation in continuations {
continuation.resume(with: result)
}
}
}