Forked from AliSoftware/CustomCodable+PropertyWrapper.swift
Created
June 20, 2020 11:32
-
-
Save MMnasrabadi/7866912ba69c22f8d1ab03ce8aedaa7d 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