import Foundation public protocol SunoHandoffService: Sendable { func handOff(_ output: CompiledSunoOutput) async throws } public enum SunoHandoffDestination { public static let createPageURL = URL(string: "https://suno.com/create")! } public struct SunoHandoffPayload: Equatable, Sendable { public let title: String public let lyrics: String public let stylePrompt: String public init(title: String, lyrics: String, stylePrompt: String) { self.title = title self.lyrics = lyrics self.stylePrompt = stylePrompt } public func value(for field: SunoHandoffField) -> String { switch field { case .title: return title case .lyrics: return lyrics case .stylePrompt: return stylePrompt } } } public enum SunoHandoffField: String, CaseIterable, Equatable, Identifiable, Sendable { case title case lyrics case stylePrompt public var id: String { rawValue } public var displayName: String { switch self { case .title: return "Title" case .lyrics: return "Lyrics" case .stylePrompt: return "Style prompt" } } } public enum SunoFieldFillResult: Equatable, Sendable { case filled case copyRequired(String) } public struct SunoFieldFillReport: Equatable, Sendable { public let results: [SunoHandoffField: SunoFieldFillResult] public init(results: [SunoHandoffField: SunoFieldFillResult]) { self.results = results } public static func copyRequired(for fields: [SunoHandoffField], reason: String) -> SunoFieldFillReport { SunoFieldFillReport(results: Dictionary(uniqueKeysWithValues: fields.map { ($0, .copyRequired(reason)) })) } } public protocol SunoFieldFilling: Sendable { func fill(_ payload: SunoHandoffPayload) async -> SunoFieldFillReport }