Skip to content

Instantly share code, notes, and snippets.

@Nadohs
Last active December 30, 2015 07:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Nadohs/9e8764f60cf6ff20a3ec to your computer and use it in GitHub Desktop.
Save Nadohs/9e8764f60cf6ff20a3ec to your computer and use it in GitHub Desktop.
EnumConvertible

Example Enums:

enum SessionChannel: Int {
    case NeedsAuthentication = 0
    case VerifiedUser = 1
}


enum SessionEvent {
    case NeedsAuthentication(Int)
    case VerifiedUser(Float)
}


extension SessionEvent: EnumConvertible {}

extension SessionChannel: EnumConvertible{
    
    static var allCases:[SessionChannel] {
        return [
            .NeedsAuthentication,
            .VerifiedUser
        ]
    }
}

Example Conversion:

let x = SessionEvent.NeedsAuthentication(5)

if let y:SessionChannel = x.toEnum(){
    print(y)
    //NeedsAuthentication
}

How EnumConvertible Works:

protocol EnumConvertible{
    
    ///`allCases:`implement to return array of each case value in enum
    ///
    ///**NOTE:** Only required if converting to conforming type.
    static var allCases:[Self] { get }
    var strValue:String { get }
    func toEnum<T:EnumConvertible>() -> T?
}

extension EnumConvertible{
    var strValue:String {
        let this = "\(self)"
        let startIndex = this.startIndex
        
        var start = 0
        var end = startIndex.distanceTo(this.endIndex)
        
        let startRange = this.rangeOfString(".")
        let endRange   = this.rangeOfString("(")
        
        if let index = startRange?.startIndex{
            start = startIndex.distanceTo(index)+1
        }
        
        if let index = endRange?.startIndex{
            end = startIndex.distanceTo(index)
        }
        
        let stripped = this[ startIndex.advancedBy(start)..<startIndex.advancedBy(end)]
        
        return stripped
    }
    
    func toEnum<T:EnumConvertible>() -> T?{
        let val = strValue
        
        if T.allCases.isEmpty{
            assert(false,"implement allCases() for type <\(self.dynamicType)> to satisfy EnumConvertible requirements")
        }
        
        for x in T.allCases{
            if val == x.strValue{
                return x
            }
        }
        return nil
    }
    
    // default implementation
    static var allCases:[Self] { return [] }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment