Created
February 5, 2024 07:13
-
-
Save Hungs20/aba4df28aa80b53c715542b3caaf8395 to your computer and use it in GitHub Desktop.
Flexible codable
This file contains 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
extension KeyedDecodingContainer { | |
enum FlexibleValue<T: Decodable>: Decodable { | |
case int(Int) | |
case string(String) | |
case double(Double) | |
case float(Float) | |
case bool(Bool) | |
case null | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
if container.decodeNil() { | |
self = .null | |
return | |
} | |
if let intValue = try? container.decode(Int.self) { | |
self = .int(intValue) | |
} else if let stringValue = try? container.decode(String.self) { | |
self = .string(stringValue) | |
} else if let doubleValue = try? container.decode(Double.self) { | |
self = .double(doubleValue) | |
} else if let boolValue = try? container.decode(Bool.self) { | |
self = .bool(boolValue) | |
} else { | |
throw DecodingError.typeMismatch(FlexibleValue.self, DecodingError.Context(codingPath: container.codingPath, debugDescription: "Unsupported flexible value type")) | |
} | |
} | |
} | |
func decodeFlexibleValue<T>(_ key: Key) throws -> T? where T: Decodable, T: LosslessStringConvertible { | |
do { | |
let flexibleValue = try self.decode(FlexibleValue<T>.self, forKey: key) | |
switch flexibleValue { | |
case .int(let intValue): | |
return T(String(intValue)) | |
case .string(let stringValue): | |
return T(stringValue) | |
case .double(let doubleValue): | |
return T(String(doubleValue)) | |
case .float(let floatValue): | |
return T(String(floatValue)) | |
case .bool(let boolValue): | |
return T(String(boolValue)) | |
case .null: | |
return nil | |
} | |
} catch { | |
return nil | |
} | |
} | |
func decodeFlexibleValue<T>(_ key: Key, defaultValue: T) throws -> T where T: Decodable, T: LosslessStringConvertible { | |
return try self.decodeFlexibleValue(key) ?? defaultValue | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment