Skip to content

Instantly share code, notes, and snippets.

@MaximKotliar
Last active November 28, 2022 18:35
Show Gist options
  • Save MaximKotliar/b528a792b3c419391339836e4c73354f to your computer and use it in GitHub Desktop.
Save MaximKotliar/b528a792b3c419391339836e4c73354f to your computer and use it in GitHub Desktop.
import Foundation
public enum SafeCodableEnum<Nested: RawRepresentable & Codable> where Nested.RawValue: Codable {
case defined(Nested)
case other(Nested.RawValue)
}
extension SafeCodableEnum: RawRepresentable {
public init?(rawValue: Nested.RawValue) {
if let defined = Nested(rawValue: rawValue) {
self = .defined(defined)
} else {
self = .other(rawValue)
}
}
public var rawValue: Nested.RawValue {
switch self {
case .defined(let nested):
return nested.rawValue
case .other(let rawValue):
return rawValue
}
}
}
extension SafeCodableEnum: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
do {
self = .defined(try container.decode(Nested.self))
} catch {
do {
let otherRawValue = try container.decode(Nested.RawValue.self)
self = .other(otherRawValue)
print("New case detected, please add \(otherRawValue) to \(Nested.self)")
} catch {
fatalError("Fail to decode .other case for SafeCodableEnum. Error: \(error)")
}
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(rawValue)
}
}
extension SafeCodableEnum: Equatable where Nested: Equatable, Nested.RawValue: Equatable {}
public extension RawRepresentable where RawValue: Codable, Self: Codable {
typealias Safe = SafeCodableEnum<Self>
}
@MaximKotliar
Copy link
Author

MaximKotliar commented Dec 6, 2021

Helps to wrap any Codable enum with safe .other(someValue) case when decoding fails.

Usage example

enum Fruit: String, Codable {
    case apple
    case orange
    case strawberry
}

struct Garden: Codable {
    let fruits: [Fruit.Safe]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment