IBEnum.swift 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. //
  2. // Created by jason akakpo on 27/06/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import Foundation
  6. /**
  7. A protocol provides extension method for converting `String` into `enum`.
  8. Because `@IBInspectable` property can not support `enum` directly. To provide both `enum` API in code and `@IBInspectable` supported type `String` in Interface Builder, we use `IBEnum` to bridge Swift `enum` and `String`
  9. */
  10. public protocol IBEnum {
  11. /**
  12. Initializes a swift `enum` with provided optional string
  13. - Parameter string: The optional string to be converted into `enum`.
  14. */
  15. init?(string: String?)
  16. }
  17. extension IBEnum {
  18. init(string: String?, default defaultValue: Self) {
  19. self = Self(string: string) ?? defaultValue
  20. }
  21. }
  22. /// IBEnum provide default initializer for RawRepresentable Enum
  23. #if swift(>=4.2)
  24. public extension IBEnum where Self: RawRepresentable & CaseIterable {
  25. init?(string: String?) {
  26. if let item = getCase(for: string, from: iterateEnum(from: Self.self)) {
  27. self = item
  28. } else {
  29. return nil
  30. }
  31. }
  32. }
  33. #else
  34. public extension IBEnum where Self: RawRepresentable & Hashable {
  35. init?(string: String?) {
  36. if let item = getCase(for: string, from: iterateEnum(from: Self.self)) {
  37. self = item
  38. } else {
  39. return nil
  40. }
  41. }
  42. }
  43. #endif
  44. private func getCase<T: IBEnum & RawRepresentable>(for string: String?, from iterator: AnyIterator<T>) -> T? {
  45. let lowerString = string?.lowercased()
  46. for item in iterator {
  47. if String(describing: item.rawValue).lowercased() == lowerString {
  48. return item
  49. }
  50. }
  51. return nil
  52. }