Created
October 16, 2019 13:38
-
-
Save AliSoftware/eff27d01bf0b4b74c0239001fd0c4f50 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 | |
protocol TransformerType { | |
associatedtype BaseType | |
associatedtype TypeForCoding: Codable | |
static var encodeTransform: (BaseType) throws -> TypeForCoding { get } | |
static var decodeTransform: (TypeForCoding) throws -> BaseType { get } | |
} | |
@propertyWrapper | |
struct CustomCodable<Transformer: TransformerType> { | |
var wrappedValue: Transformer.BaseType | |
} | |
extension CustomCodable: Codable { | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let encoded = try container.decode(Transformer.TypeForCoding.self) | |
self.wrappedValue = try Transformer.decodeTransform(encoded) | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
let encoded = try Transformer.encodeTransform(self.wrappedValue) | |
try container.encode(encoded) | |
} | |
} |
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
// Declare a custom transform | |
enum IntAsPoundString: TransformerType { | |
static let encodeTransform = { (base: Int) throws -> String in "#\(base)#" } | |
static let decodeTransform = { (encoded: String) throws -> Int in Int(encoded.replacingOccurrences(of: "#", with: "")) ?? 0 } | |
} | |
struct Article: Codable { | |
@CustomCodable<IntAsPoundString> | |
var id: Int | |
var name: String | |
} | |
// Demo | |
let art1 = Article(id: 42, name: "H2G2") | |
let encoder = JSONEncoder() | |
encoder.outputFormatting = .prettyPrinted | |
let j1 = String(data: try encoder.encode(art1), encoding: .utf8) ?? "<nil>" | |
print(j1) | |
/* | |
{ | |
"id" : "#42#", | |
"name" : "H2G2" | |
} | |
*/ | |
let art1decoded = try JSONDecoder().decode(Article.self, from: j1.data(using: .utf8)!) | |
print(art1decoded.id, art1decoded.name) | |
/* 42 H2G2 */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment