Skip to content

Instantly share code, notes, and snippets.

@paulcadman
Last active July 12, 2018 14:01
Show Gist options
  • Save paulcadman/d043f28d623f1bd2d647bf755309b121 to your computer and use it in GitHub Desktop.
Save paulcadman/d043f28d623f1bd2d647bf755309b121 to your computer and use it in GitHub Desktop.
Feature Enum
enum Feature<T: Decodable>: Decodable {
case disabled
case enabled(configuration: T)
init(from decoder: Decoder) throws {
if let _ = try? EmptyObject.init(from: decoder) {
self = .disabled
return
}
let parsed = try T.init(from: decoder)
self = .enabled(configuration: parsed)
}
}
struct EmptyConfiguration: Decodable {}
typealias ToggleFeature = Feature<EmptyConfiguration>
struct EmptyObject: Decodable {
enum Errors: Error {
case containsUnexpected(keys: [String])
}
init(from decoder: Decoder) throws {
let stringKeys = try decoder.container(keyedBy: StringCodingKey.self).allKeys
if !stringKeys.isEmpty {
throw Errors.containsUnexpected(keys: stringKeys.map { $0.stringValue })
}
}
private struct StringCodingKey: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int?
init?(intValue: Int) {
return nil
}
}
}
struct AccountsConfig: Decodable {
var countryCode: String
}
struct FeatureConfig: Decodable {
var interac: ToggleFeature
var accounts: Feature<AccountsConfig>
}
// Example: interac disabled, accounts enabled with configuration
let interacDisabledAccountsEnabled = """
{
"interac": {},
"accounts": { "countryCode": "CA" }
}
"""
let config = try JSONDecoder().decode(FeatureConfig.self, from: json.data(using: .utf8)!)
config.interac // disabled
if case .enabled(let accountConfig) = config.accounts {
accountConfig.countryCode // CA
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment