import Foundation /// A service that captures audio from a microphone for the Recording feature. /// /// ``RecordingView`` attaches the service to its model at initialization, so the audio capture can be swapped without touching the feature's /// state machine — for example, with a real microphone backend in the app, or with a mock in unit tests. public protocol Capturing: Sendable { // MARK: Properties /// The stream of events the service emits outside its method calls. /// /// Defaults to an empty stream that finishes immediately, for services that emit no events. var events: AsyncStream { get } // MARK: Methods /// Starts a new audio recording from the microphone. func start() async throws /// Pauses the ongoing recording. func pause() async throws /// Resumes a paused recording. func resume() async throws /// Stops the recording. /// /// - Returns: The location of the audio file captured since the recording started. func stop() async throws -> URL } // MARK: - Implementations public extension Capturing { /// The empty stream of events, which finishes immediately, for services that emit no events. var events: AsyncStream { AsyncStream { continuation in continuation.finish() } } } // MARK: - Events /// An event emitted by a ``Capturing`` service outside its method calls. public enum CapturingEvent: Equatable, Sendable { /// The system interrupted the ongoing capture, pausing it. case interrupted /// The system ended the interruption of the capture, hinting whether the capture may resume right away. case interruptionEnded(shouldResume: Bool) }