Skip to content

Instantly share code, notes, and snippets.

@cweinberger
Last active April 13, 2020 15:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cweinberger/a2979b0801d88f10be4919e6dd9f6b3d to your computer and use it in GitHub Desktop.
Save cweinberger/a2979b0801d88f10be4919e6dd9f6b3d to your computer and use it in GitHub Desktop.
Auto-conform your enums types that you want to store in MySQL to `MySQLDataConvertible` and `ReflectionDecodable`. Avoids a lot of boilerplate!
/* NOTE: check out 3-MySQLDataConvertibleEnum_Better_Version.swift. */
import Fluent
import FluentMySQL
import Vapor
protocol MySQLDataConvertibleEnum: MySQLDataConvertible, ReflectionDecodable, CaseIterable { }
extension MySQLDataConvertibleEnum where Self: RawRepresentable, Self.RawValue == String {
func convertToMySQLData() -> MySQLData {
return MySQLData(string: self.rawValue)
}
static func convertFromMySQLData(_ mysqlData: MySQLData) throws -> Self {
guard let val = Self(rawValue: mysqlData.string()) else {
throw Abort(.internalServerError, reason: "Could not convert MySQLData to `\(String(reflecting: type(of: self)))`")
}
return val
}
}
extension MySQLDataConvertibleEnum where Self: RawRepresentable, Self: CaseIterable, Self.RawValue == String {
static func reflectDecoded() throws -> (Self, Self) {
let cases = Array(Self.allCases)
assert(cases.count >= 2, "[MySQLDataConvertibleEnum] In order to use the default extensions, your enum `\(String(reflecting: type(of: self)))` has to have at least two cases!")
return (cases[0], cases[1])
}
}
extension RawRepresentable {
init?(rawValue: RawValue?) {
guard
let rawValue = rawValue,
let val = Self.init(rawValue: rawValue)
else {
return nil
}
self = val
}
}
enum ArticleStatus: String, Content, CaseIterable {
case published
case scheduled
case unpublished
}
extension ArticleStatus: MySQLDataConvertibleEnum {} // <- This is all you need
import Fluent
import FluentMySQL
import Vapor
protocol MySQLDataConvertibleEnum: MySQLEnumType, CaseIterable { }
extension MySQLDataConvertibleEnum where Self: RawRepresentable, Self: CaseIterable, Self.RawValue == String {
static func reflectDecoded() throws -> (Self, Self) {
let cases = Array(Self.allCases)
assert(cases.count >= 2, "[MySQLDataConvertibleEnum] In order to use the default extensions, your enum `\(String(reflecting: type(of: self)))` has to have at least two cases!")
return (cases[0], cases[1])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment