Last active
November 28, 2022 18:35
-
-
Save MaximKotliar/b528a792b3c419391339836e4c73354f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Helps to wrap any
Codable
enum with safe.other(someValue)
case when decoding fails.Usage example