//
//  RawRepresentableCodable.swift
//  MVMCoreUI
//
//  Created by Scott Pfeil on 9/14/23.
//  Copyright © 2023 Verizon Wireless. All rights reserved.
//

import Foundation

public protocol RawRepresentableCodable: RawRepresentable, Codable where RawValue: Hashable & Decodable {
    static var mapping: [RawValue: Self] { get }
    static var defaultValue: Self? { get }
}

public enum RawRepresentableCodableError: Swift.Error {
    case invalid(value: String)
}

extension RawRepresentableCodable {

    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let rawValue = try container.decode(RawValue.self)
        if let found = Self(rawValue: rawValue) {
            self = found
        } else if let found = Self.mapping[rawValue] {
            self = found
        } else if let defaultValue = Self.defaultValue {
            self = defaultValue
        } else {
            throw RawRepresentableCodableError.invalid(value: "\(rawValue)")
        }
    }
}
