Enum of tuples in Swift
SwiftSwift 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
Create an Enumeration as Int.
For example:
https://github.com/rhodgkins/SwiftHTTPStatusCodes/blob/master/Sources/HTTPStatusCodes.swift