DictionaryInitializable.swift 1.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
//
//  DictionaryInitializable.swift
//  Lottie
//
//  Created by Marcelo Fabri on 5/5/22.
//

// MARK: - InitializableError

enum InitializableError: Error {
  case invalidInput(file: StaticString = #file, line: UInt = #line)
}

// MARK: - DictionaryInitializable

protocol DictionaryInitializable {

  init(dictionary: [String: Any]) throws

}

// MARK: - AnyInitializable

protocol AnyInitializable {

  init(value: Any) throws

}

extension Dictionary {

  @_disfavoredOverload
  func value<T, KeyType: RawRepresentable>(
    for key: KeyType,
    file: StaticString = #file,
    line: UInt = #line)
    throws -> T where KeyType.RawValue == Key
  {
    guard let value = self[key.rawValue] as? T else {
      throw InitializableError.invalidInput(file: file, line: line)
    }
    return value
  }

  func value<T: AnyInitializable, KeyType: RawRepresentable>(
    for key: KeyType,
    file: StaticString = #file,
    line: UInt = #line)
    throws -> T where KeyType.RawValue == Key
  {
    if let value = self[key.rawValue] as? T {
      return value
    }

    if let value = self[key.rawValue] {
      return try T(value: value)
    }

    throw InitializableError.invalidInput(file: file, line: line)
  }

}

// MARK: - AnyInitializable + AnyInitializable

extension [Double]: AnyInitializable {

  init(value: Any) throws {
    guard let array = value as? [Double] else {
      throw InitializableError.invalidInput()
    }
    self = array
  }

}