specta-swift 0.0.3

Export your Rust types to Swift
Documentation
// This file has been generated by Specta. DO NOT EDIT.
import Foundation

/// Mixed enum with both string-like and data variants
public enum ApiResult {
    case success
    case successWithData(ApiResultSuccessWithDataData)
    case error(ApiResultErrorData)
    case loading
}
public struct ApiResultSuccessWithDataData: Codable {
    public let data: String
    public let statusCode: UInt16

    private enum CodingKeys: String, CodingKey {
        case data = "data"
        case statusCode = "status_code"
    }
}

public struct ApiResultErrorData: Codable {
    public let message: String
    public let code: UInt32
}

// MARK: - ApiResult Codable Implementation
extension ApiResult: Codable {
    private enum CodingKeys: String, CodingKey {
        case success = "Success"
        case successWithData = "SuccessWithData"
        case error = "Error"
        case loading = "Loading"
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        if container.allKeys.count != 1 {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Invalid number of keys found, expected one.")
            )
        }

        let key = container.allKeys.first!
        switch key {
        case .success:
            self = .success
        case .successWithData:
            let data = try container.decode(ApiResultSuccessWithDataData.self, forKey: .successWithData)
            self = .successWithData(data)
        case .error:
            let data = try container.decode(ApiResultErrorData.self, forKey: .error)
            self = .error(data)
        case .loading:
            self = .loading
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        switch self {
        case .success:
            try container.encodeNil(forKey: .success)
        case .successWithData(let data):
            try container.encode(data, forKey: .successWithData)
        case .error(let data):
            try container.encode(data, forKey: .error)
        case .loading:
            try container.encodeNil(forKey: .loading)
        }
    }
}


/// String enum with more complex values
public enum Environment: Codable {
    case development
    case staging
    case production
    case testing
}

/// Complex enum with multiple data variants
public enum EventType {
    case userCreated
    case userUpdated(EventTypeUserUpdatedData)
    case userDeleted(EventTypeUserDeletedData)
    case systemEvent(EventTypeSystemEventData)
}
public struct EventTypeUserUpdatedData: Codable {
    public let userId: UInt32
    public let changes: [(String, String)]

    private enum CodingKeys: String, CodingKey {
        case userId = "user_id"
        case changes = "changes"
    }
}

public struct EventTypeUserDeletedData: Codable {
    public let userId: UInt32
    public let reason: String

    private enum CodingKeys: String, CodingKey {
        case userId = "user_id"
        case reason = "reason"
    }
}

public struct EventTypeSystemEventData: Codable {
    public let component: String
    public let level: String
    public let message: String
}

// MARK: - EventType Codable Implementation
extension EventType: Codable {
    private enum CodingKeys: String, CodingKey {
        case userCreated = "UserCreated"
        case userUpdated = "UserUpdated"
        case userDeleted = "UserDeleted"
        case systemEvent = "SystemEvent"
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        if container.allKeys.count != 1 {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Invalid number of keys found, expected one.")
            )
        }

        let key = container.allKeys.first!
        switch key {
        case .userCreated:
            self = .userCreated
        case .userUpdated:
            let data = try container.decode(EventTypeUserUpdatedData.self, forKey: .userUpdated)
            self = .userUpdated(data)
        case .userDeleted:
            let data = try container.decode(EventTypeUserDeletedData.self, forKey: .userDeleted)
            self = .userDeleted(data)
        case .systemEvent:
            let data = try container.decode(EventTypeSystemEventData.self, forKey: .systemEvent)
            self = .systemEvent(data)
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        switch self {
        case .userCreated:
            try container.encodeNil(forKey: .userCreated)
        case .userUpdated(let data):
            try container.encode(data, forKey: .userUpdated)
        case .userDeleted(let data):
            try container.encode(data, forKey: .userDeleted)
        case .systemEvent(let data):
            try container.encode(data, forKey: .systemEvent)
        }
    }
}


/// String enum for file types
public enum FileType: Codable {
    case image
    case video
    case audio
    case document
    case archive
    case unknown
}

/// Comprehensive example showcasing string enums and custom Codable implementations
/// 
/// This example demonstrates how specta-swift handles string enums, mixed enums,
/// and generates appropriate Codable implementations for different enum patterns.
/// Simple string enum (will be converted to Swift String enum with Codable)
public enum HttpStatus: Codable {
    case ok
    case created
    case accepted
    case noContent
    case badRequest
    case unauthorized
    case notFound
    case internalServerError
}

/// String enum for job states
public enum JobState: Codable {
    case queued
    case running
    case paused
    case completed
    case failed
    case cancelled
}

/// Mixed enum with complex variants
public enum NotificationType {
    case email
    case push
    case sms
    case webhook(NotificationTypeWebhookData)
    case inApp(NotificationTypeInAppData)
}
public struct NotificationTypeWebhookData: Codable {
    public let url: String
    public let headers: [(String, String)]
    public let retryCount: UInt32

    private enum CodingKeys: String, CodingKey {
        case url = "url"
        case headers = "headers"
        case retryCount = "retry_count"
    }
}

public struct NotificationTypeInAppData: Codable {
    public let title: String
    public let message: String
    public let priority: String
}

// MARK: - NotificationType Codable Implementation
extension NotificationType: Codable {
    private enum CodingKeys: String, CodingKey {
        case email = "Email"
        case push = "Push"
        case sms = "Sms"
        case webhook = "Webhook"
        case inApp = "InApp"
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        if container.allKeys.count != 1 {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Invalid number of keys found, expected one.")
            )
        }

        let key = container.allKeys.first!
        switch key {
        case .email:
            self = .email
        case .push:
            self = .push
        case .sms:
            self = .sms
        case .webhook:
            let data = try container.decode(NotificationTypeWebhookData.self, forKey: .webhook)
            self = .webhook(data)
        case .inApp:
            let data = try container.decode(NotificationTypeInAppData.self, forKey: .inApp)
            self = .inApp(data)
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        switch self {
        case .email:
            try container.encodeNil(forKey: .email)
        case .push:
            try container.encodeNil(forKey: .push)
        case .sms:
            try container.encodeNil(forKey: .sms)
        case .webhook(let data):
            try container.encode(data, forKey: .webhook)
        case .inApp(let data):
            try container.encode(data, forKey: .inApp)
        }
    }
}


/// Enum with generic type parameter
public enum Result<T, E>: Codable {
    case ok(T)
    case err(E)
}

/// Complex mixed enum
public enum UserAction {
    case login
    case logout
    case updateProfile(UserActionUpdateProfileData)
    case changePassword(UserActionChangePasswordData)
    case deleteAccount
}
public struct UserActionUpdateProfileData: Codable {
    public let name: String
    public let email: String
    public let avatarUrl: String?

    private enum CodingKeys: String, CodingKey {
        case name = "name"
        case email = "email"
        case avatarUrl = "avatar_url"
    }
}

public struct UserActionChangePasswordData: Codable {
    public let oldPassword: String
    public let newPassword: String

    private enum CodingKeys: String, CodingKey {
        case oldPassword = "old_password"
        case newPassword = "new_password"
    }
}

// MARK: - UserAction Codable Implementation
extension UserAction: Codable {
    private enum CodingKeys: String, CodingKey {
        case login = "Login"
        case logout = "Logout"
        case updateProfile = "UpdateProfile"
        case changePassword = "ChangePassword"
        case deleteAccount = "DeleteAccount"
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        if container.allKeys.count != 1 {
            throw DecodingError.dataCorrupted(
                DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Invalid number of keys found, expected one.")
            )
        }

        let key = container.allKeys.first!
        switch key {
        case .login:
            self = .login
        case .logout:
            self = .logout
        case .updateProfile:
            let data = try container.decode(UserActionUpdateProfileData.self, forKey: .updateProfile)
            self = .updateProfile(data)
        case .changePassword:
            let data = try container.decode(UserActionChangePasswordData.self, forKey: .changePassword)
            self = .changePassword(data)
        case .deleteAccount:
            self = .deleteAccount
        }
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        switch self {
        case .login:
            try container.encodeNil(forKey: .login)
        case .logout:
            try container.encodeNil(forKey: .logout)
        case .updateProfile(let data):
            try container.encode(data, forKey: .updateProfile)
        case .changePassword(let data):
            try container.encode(data, forKey: .changePassword)
        case .deleteAccount:
            try container.encodeNil(forKey: .deleteAccount)
        }
    }
}