Enum of tuples in Swift

Swift

Swift Problem Overview


Is this possible to create a enum of Tuples in Swift?

I'd like to build something like:

enum ErrorCode: (Int, String) {
    case Generic_Error = (0, "Unknown")
    case DB_Error = (909, "Database")
}

But it doesn't compile... Is there a way to obtain a similar result?

Swift Solutions


Solution 1 - Swift

Swift enumerations cannot have Tuples as a raw value type.

Alternative approaches include storing the code and deriving a description from that:

enum ErrorCode: Int, CustomStringConvertible {
    case Generic = 0
    case DB = 909
    
    var description: String {
        switch self {
        case .Generic:
            return "Unknown"
        case .DB:
            return "Database"
        }
    }
}

...or storing associated values for code and description in the enumeration cases themselves:

enum Error {
    case Generic(Int, String)
    case DB(Int, String)
}

If you're just looking for constant values, @matt's suggestion of organizing them within a struct would work, too.

Solution 2 - Swift

It depends what you mean by "similar". What I do is use a Struct with static constant properties:

struct Trouble {
    static let Generic_Error = (0, "Unknown")
    static let DB_Error = (909, "Database")
}

Now things like Trouble.Generic_Error are usable throughout your code.

Solution 3 - Swift

You can conform to RawRepresentable and use (Int, String) as the Self.RawValue associated type.

enum ErrorCode: RawRepresentable {
    case Generic_Error
    case DB_Error
    
    var rawValue: (Int, String) {
        switch self {
        case .Generic_Error: return (0, "Unknown")
        case .DB_Error: return (909, "Database")
        }
    }
    
    init?(rawValue: (Int, String)) {
        switch rawValue {
        case (0, "Unknown"): self = .Generic_Error
        case (909, "Database"): self = .DB_Error
        default: return nil
        }
    }
}

Solution 4 - Swift

you can do such thing, maybe:

enum ErrorCode {
    case Generic_Error
    case DB_Error

    func values() -> (code: Int!, description: String?)! {
        switch self {
        case .Generic_Error:
            return (0, "Unknown")
        case .DB_Error:
            return (909, "Database")
        }
    }
}

and you can do such thing later:

let errorCode: ErrorCode = ErrorCode.Generic_Error;
if (errorCode.values().code == 0) {
    // do the business here...
}

Solution 5 - Swift

Create your enum and add a var of tuple type (String, String).

enum SomeType {
    case type1
    case type2
    case type3

    var typeNameAndDescription: (name: String, description: String) {
       switch self {
       case .type1:
            return ("type1 name", "type1 description")
        case .type2:
            return ("type2 name", "type2 description")
        case .type3:
            return ("type3 name", "type3 description")
       }
    }
}

and later:

let myType = SomeType.type1
let typeName = myType.typeNameAndDescription.name
let typeDescription = myType.typeNameAndDescription.description

Solution 6 - Swift

My solution to keep the enum, was to create the get method for the rawValue var:

enum LoadingType {
  case poster
  case movie
  case refresh
  
  var rawValue: (file: String, anim: String) {
    get {
      switch self {
      case .movie:
        return ("poster_loading", "LoadingView")
      case .poster:
        return ("loading", "LoadingView")
      case .refresh:
        return ("loading", "RefreshView")
      }
    }
  }
}

With this code, you can even call each of your Tuple elements by a name:

self.type.rawValue.file

Solution 7 - Swift

I think I would change your code to something like this:

enum ErrorCode {
	case generic, db

	var message: String {
		switch self {
		case .generic:
			return "Unknown"
		case .db:
			return "Database"
		}
	}
	var code: Int {
		switch self {
		case .generic:
			return 0
		case .db:
			return 909
		}
	}
}

I feel this would make it much more easier to use like so:

let error = ErrorCode.generic
print("Error Code: \(error.code), Message: \(error.message)")

Solution 8 - Swift

enum ErrorCode {
    case Generic_Error
    case DB_Error
    
    public var code:Int{
        switch self {
        case .Generic_Error: return 0
        case .DB_Error: return 909
        }
    }
        
    public var name:String{
        switch self {
        case .Generic_Error: return "Unknown"
        case .DB_Error: return "Database"
        }
    }
}

using:

let err:ErrorCode = .Generic_Error
print(err.code)   //0
print(err.name)   //Unknown

Solution 9 - Swift

This is what I did in a similar situation. Use an associated data enum, with default values (you can even name the values in the tuple if you like). Then add a simple function that returns the tuple based on self.


    enum ErrorCode {
        case Generic_Error( code: Int = 0, desc: String = "Unknown")
        case DB_Error( code: Int = 909, desc: String = "Database")
    
    
        func getCodeDescription() -> (Int, String) {
            switch self {
                case let .Generic_Error(code, desc): return (code, desc)
                case let .DB_Error(code, desc):  return(code, desc)
            }
        }
    }

Later

    var errorCode: Int
    var errorDesc: String
    
    let myError: ErrorCode = .DB_Error() // let it take the default values 
    (errorCode, errorDesc) = myError.getCodeDescription()

Solution 10 - Swift

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatterGoalView Question on Stackoverflow
Solution 1 - SwiftmatttView Answer on Stackoverflow
Solution 2 - SwiftmattView Answer on Stackoverflow
Solution 3 - Swiftdjtech42View Answer on Stackoverflow
Solution 4 - SwiftholexView Answer on Stackoverflow
Solution 5 - SwiftAu RisView Answer on Stackoverflow
Solution 6 - Swiftrusito23View Answer on Stackoverflow
Solution 7 - SwiftatulkhatriView Answer on Stackoverflow
Solution 8 - Swiftdr OXView Answer on Stackoverflow
Solution 9 - SwiftRichWaltView Answer on Stackoverflow
Solution 10 - SwiftIstván PatóView Answer on Stackoverflow