import Foundation /// Protocol all upload backends conform to. public protocol FeedUploader: Sendable { /// Uploads the full updated `social.org` content to the remote host. func upload(content: String) async throws } public enum UploadError: Error, Sendable { case uploadFailed(statusCode: Int) case networkError(underlying: String) case invalidConfiguration(String) case fileNotFound } extension UploadError: LocalizedError { public var errorDescription: String? { switch self { case .uploadFailed(let code): return "Upload failed with HTTP \(code)." case .networkError(let msg): return "Network error: \(msg)" case .invalidConfiguration(let msg): return "Upload not configured: \(msg)" case .fileNotFound: return "Remote file not found." } } } public enum UploadMethod: String, CaseIterable, Sendable { case vfile case github case codeberg case webdav }