Created
February 16, 2022 05:48
-
-
Save Pretz/e608759f38087892bd02102d22fb57a3 to your computer and use it in GitHub Desktop.
StringCodable
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
struct User: Codable, Equatable { | |
@StringDecodable | |
var identifier: Int | |
@StringCodable | |
var anotherID: UInt64 | |
} | |
let user = User(identifier: 100, anotherID: 1030402030) | |
user.anotherID | |
let val = try JSONEncoder().encode(user) | |
String(bytes: val, encoding: .utf8) | |
let str1 = """ | |
{ "anotherID": 1030402030, | |
"identifier": 100 } | |
""" | |
let user1 = try JSONDecoder().decode(User.self, from: Data(str1.utf8)) | |
let str2 = """ | |
{ "anotherID": "1030402030", | |
"identifier": "100" } | |
""" | |
let user2 = try JSONDecoder().decode(User.self, from: Data(str2.utf8)) | |
user1 == user2 // true | |
// Prints {"anotherID":"1030402030","identifier":100} | |
print(String(decoding: try JSONEncoder().encode(user), as: UTF8.self)) |
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
@propertyWrapper | |
public struct StringDecodable<T: Decodable & LosslessStringConvertible>: Decodable { | |
public var wrappedValue: T | |
public init(wrappedValue: T) { self.wrappedValue = wrappedValue } | |
public init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let convertedValue: T | |
do { | |
convertedValue = try container.decode(T.self) | |
} catch { | |
let stringInteger = try container.decode(String.self) | |
// Lazy. Better to throw a more specific error | |
guard let value = T(stringInteger) else { throw error } | |
convertedValue = value | |
} | |
self.wrappedValue = convertedValue | |
} | |
} | |
extension StringDecodable: Encodable where T: Encodable { | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(wrappedValue) | |
} | |
} | |
@propertyWrapper | |
public struct StringCodable<T: Decodable & LosslessStringConvertible>: Codable { | |
public var wrappedValue: T | |
public init(wrappedValue: T) { self.wrappedValue = wrappedValue } | |
public init(from decoder: Decoder) throws { | |
wrappedValue = try StringDecodable(from: decoder).wrappedValue | |
} | |
public func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(wrappedValue.description) | |
} | |
} | |
extension StringDecodable: Equatable where T: Equatable { } | |
extension StringDecodable: Hashable where T: Hashable { } | |
extension StringCodable: Equatable where T: Equatable { } | |
extension StringCodable: Hashable where T: Hashable { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment