Created
April 30, 2020 21:08
-
-
Save zwaldowski/152fc4753614f99e9ca40822810c11cb to your computer and use it in GitHub Desktop.
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
import Foundation | |
@propertyWrapper | |
struct OrString<Wrapped>: Decodable where Wrapped: Decodable, Wrapped: LosslessStringConvertible { | |
var wrappedValue: Wrapped | |
init(wrappedValue: Wrapped) { | |
self.wrappedValue = wrappedValue | |
} | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
do { | |
wrappedValue = try container.decode(Wrapped.self) | |
} catch DecodingError.typeMismatch(_, let context) { | |
let stringValue = try container.decode(String.self) | |
guard let parsedValue = Wrapped(stringValue) else { | |
let context = DecodingError.Context( | |
codingPath: context.codingPath, | |
debugDescription: "Could not re-create \(Wrapped.self) from String") | |
throw DecodingError.typeMismatch(String.self, context) | |
} | |
wrappedValue = parsedValue | |
} | |
} | |
} | |
extension OrString: Encodable where Wrapped: Encodable {} | |
extension OrString: Equatable where Wrapped: Equatable {} | |
extension OrString: Hashable where Wrapped: Hashable {} | |
extension OrString: CustomStringConvertible { | |
var description: String { | |
return String(describing: wrappedValue) | |
} | |
} | |
extension OrString: CustomDebugStringConvertible { | |
var debugDescription: String { | |
return String(reflecting: wrappedValue) | |
} | |
} | |
// MARK: - | |
extension Decimal: LosslessStringConvertible { | |
public init?(_ text: String) { | |
self.init(string: text, locale: nil) | |
} | |
} | |
// MARK: - | |
struct Foo: Equatable, Decodable { | |
var bar: String | |
@OrString var moneyAmount: Decimal | |
} | |
let x = try JSONDecoder().decode(Foo.self, from: Data(""" | |
{"bar": "baz", "moneyAmount": 9001.202} | |
""".utf8)) | |
print(x) | |
let y = try JSONDecoder().decode(Foo.self, from: Data(""" | |
{"bar": "baz", "moneyAmount": "9001.202"} | |
""".utf8)) | |
print(y) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment