Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jordanebelanger/31a1e1d818e3197933fd5e0deb2fd58f to your computer and use it in GitHub Desktop.
Save jordanebelanger/31a1e1d818e3197933fd5e0deb2fd58f to your computer and use it in GitHub Desktop.
/// Raw representable `Codable` property wrapper used to instantiate to a `RawRepresentable` type if the `rawValue`decoded is supported
/// by the generic `RawRepresentableValue` type. This can be useful when you want to decode a set of constant values
/// specified inside `RawRepresentable` enum yet default to the `rawValue` if the decoded `rawValue` is unsupported.
///
/// For example, using this property wrapper you could decode an enum specifying a list of error code such as:
///
/// enum ErrorCode: String, Codable {
/// case notFound, unauthorized, badRequest
/// }
///
/// while defaulting to the rawValue in case the decoded rawValue is unsupported/unknown.
@propertyWrapper
public struct UnknownDefaulting<RawRepresentableValue>: Codable
where RawRepresentableValue: RawRepresentable, RawRepresentableValue.RawValue: Codable
{
public enum UnknownRawRepresentableValueWrapper {
case supported(_ value: RawRepresentableValue)
case unknown(_ value: RawRepresentableValue.RawValue)
}
public var value: UnknownRawRepresentableValueWrapper
public init(from decoder: Decoder) throws {
let rawValue = try RawRepresentableValue.RawValue(from: decoder)
if let value = RawRepresentableValue(rawValue: rawValue) {
self.value = .supported(value)
} else {
self.value = .unknown(rawValue)
}
}
public func encode(to encoder: Encoder) throws {
try self.wrappedValue.encode(to: encoder)
}
public var wrappedValue: RawRepresentableValue.RawValue {
switch value {
case .supported(let value):
return value.rawValue
case .unknown(let rawValue):
return rawValue
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment