Skip to content

Instantly share code, notes, and snippets.

@zwaldowski
Created April 30, 2020 21:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zwaldowski/152fc4753614f99e9ca40822810c11cb to your computer and use it in GitHub Desktop.
Save zwaldowski/152fc4753614f99e9ca40822810c11cb to your computer and use it in GitHub Desktop.
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