From 02fb6b9345ac3dcab8b320002608ffd44b096e2d Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Sat, 18 Jan 2025 20:03:11 +0100 Subject: [PATCH] Implemented the "availableData" property for the Pipe+Properties extension in the library target and also, implemented its "append()" function that appends its data concurrently. --- .../Internal/Extensions/Pipe+Properties.swift | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Library/Sources/Internal/Extensions/Pipe+Properties.swift diff --git a/Library/Sources/Internal/Extensions/Pipe+Properties.swift b/Library/Sources/Internal/Extensions/Pipe+Properties.swift new file mode 100644 index 0000000..94b27e7 --- /dev/null +++ b/Library/Sources/Internal/Extensions/Pipe+Properties.swift @@ -0,0 +1,72 @@ +import Foundation + +extension Pipe { + + // MARK: Computed + + var availableData: AsyncAvailableData { .init(self) } + +} + +// MARK: - AsyncAvailableData + +extension Pipe { + struct AsyncAvailableData { + + // MARK: Properties + + private let pipe: Pipe + + // MARK: Initialisers + + init(_ pipe: Pipe) { + self.pipe = pipe + } + + // MARK: Functions + + func append() async -> Data { + var data = Data() + + for await availableData in self { + data.append(availableData) + } + + return data + } + + } +} + +// MARK: - AsyncSequence + +extension Pipe.AsyncAvailableData: AsyncSequence { + + // MARK: Type aliases + + typealias AsyncIterator = AsyncStream.Iterator + typealias Element = Data + + // MARK: Functions + + func makeAsyncIterator() -> AsyncIterator { + AsyncStream { continuation in + pipe.fileHandleForReading.readabilityHandler = { @Sendable handler in + let data = handler.availableData + + guard !data.isEmpty else { + continuation.finish() + return + } + + continuation.yield(data) + } + + continuation.onTermination = { _ in + pipe.fileHandleForReading.readabilityHandler = nil + } + } + .makeAsyncIterator() + } + +}