@@ -10,6 +10,28 @@ enum CodingError : Error {
1010 case RuntimeError( String )
1111}
1212
13+ struct AnyKey : CodingKey {
14+ var stringValue : String
15+ var intValue : Int ?
16+
17+ init ( stringValue: String ) {
18+ self . stringValue = stringValue
19+ self . intValue = nil
20+ }
21+
22+ init ( intValue: Int ) {
23+ self . stringValue = String ( intValue)
24+ self . intValue = intValue
25+ }
26+ }
27+
28+ public var customCodingStragegy : JSONDecoder . KeyDecodingStrategy = . custom { keys in
29+ let lastComponent = keys. last!. stringValue
30+ let snakeCased = lastComponent. split ( separator: " _ " ) . map { $0. prefix ( 1 ) . uppercased ( ) + $0. dropFirst ( ) } . reduce ( " " ) { $0 + $1}
31+ let lowerFirst = snakeCased. prefix ( 1 ) . lowercased ( ) + snakeCased. dropFirst ( )
32+ return AnyKey ( stringValue: lowerFirst)
33+ }
34+
1335public extension Encodable {
1436 /**
1537 Convert this object to json data
@@ -94,9 +116,9 @@ public extension Decodable {
94116 - parameter json: The json string
95117 - parameter keyPath: for if you want something else than the root object
96118 */
97- init ( json: String , keyPath: String ? = nil ) throws {
119+ init ( json: String , keyPath: String ? = nil , codingStrategy : JSONDecoder . KeyDecodingStrategy = . convertFromSnakeCase ) throws {
98120 guard let data = json. data ( using: . utf8) else { throw CodingError . RuntimeError ( " cannot create data from string " ) }
99- try self . init ( data: data, keyPath: keyPath)
121+ try self . init ( data: data, keyPath: keyPath, codingStrategy : codingStrategy )
100122 }
101123
102124 /**
@@ -105,9 +127,9 @@ public extension Decodable {
105127 - parameter data: The json data
106128 - parameter keyPath: for if you want something else than the root object
107129 */
108- init ( data: Data , keyPath: String ? = nil , codingStragegy : JSONDecoder . KeyDecodingStrategy = . convertFromSnakeCase) throws {
130+ init ( data: Data , keyPath: String ? = nil , codingStrategy : JSONDecoder . KeyDecodingStrategy = . convertFromSnakeCase) throws {
109131 let decoder = JSONDecoder ( )
110- decoder. keyDecodingStrategy = . convertFromSnakeCase
132+ decoder. keyDecodingStrategy = codingStrategy
111133 if let keyPath = keyPath {
112134 let topLevel = try JSONSerialization . jsonObject ( with: data, options: JSONSerialization . ReadingOptions. mutableContainers)
113135 guard let nestedJson = ( topLevel as AnyObject ) . value ( forKeyPath: keyPath) else { throw CodingError . RuntimeError ( " Cannot decode data to object " ) }
0 commit comments