@@ -61,8 +61,9 @@ public enum AttributeValue: Equatable, CustomStringConvertible, Hashable {
6161 }
6262}
6363
64- // this explicit Codable implementation for AttributeValue will probably be redundant with Swift 5.5
65- extension AttributeValue : Codable {
64+ internal struct AttributeValueExplicitCodable : Codable {
65+ let attributeValue : AttributeValue
66+
6667 enum CodingKeys : String , CodingKey {
6768 case string
6869 case bool
@@ -73,7 +74,15 @@ extension AttributeValue: Codable {
7374 case intArray
7475 case doubleArray
7576 }
76-
77+
78+ enum AssociatedValueCodingKeys : String , CodingKey {
79+ case associatedValue = " _0 "
80+ }
81+
82+ internal init ( attributeValue: AttributeValue ) {
83+ self . attributeValue = attributeValue
84+ }
85+
7786 public init ( from decoder: Decoder ) throws {
7887 let container = try decoder. container ( keyedBy: CodingKeys . self)
7988
@@ -86,45 +95,83 @@ extension AttributeValue: Codable {
8695
8796 switch container. allKeys. first. unsafelyUnwrapped {
8897 case . string:
89- self = . string( try container. decode ( String . self, forKey: . string) )
98+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . string)
99+ self . attributeValue = . string( try nestedContainer. decode ( String . self, forKey: . associatedValue) )
90100 case . bool:
91- self = . bool( try container. decode ( Bool . self, forKey: . bool) )
101+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . bool)
102+ self . attributeValue = . bool( try nestedContainer. decode ( Bool . self, forKey: . associatedValue) )
92103 case . int:
93- self = . int( try container. decode ( Int . self, forKey: . int) )
104+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . int)
105+ self . attributeValue = . int( try nestedContainer. decode ( Int . self, forKey: . associatedValue) )
94106 case . double:
95- self = . double( try container. decode ( Double . self, forKey: . double) )
107+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . double)
108+ self . attributeValue = . double( try nestedContainer. decode ( Double . self, forKey: . associatedValue) )
96109 case . stringArray:
97- self = . stringArray( try container. decode ( [ String ] . self, forKey: . stringArray) )
110+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . stringArray)
111+ self . attributeValue = . stringArray( try nestedContainer. decode ( [ String ] . self, forKey: . associatedValue) )
98112 case . boolArray:
99- self = . boolArray( try container. decode ( [ Bool ] . self, forKey: . boolArray) )
113+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . boolArray)
114+ self . attributeValue = . boolArray( try nestedContainer. decode ( [ Bool ] . self, forKey: . associatedValue) )
100115 case . intArray:
101- self = . intArray( try container. decode ( [ Int ] . self, forKey: . intArray) )
116+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . intArray)
117+ self . attributeValue = . intArray( try nestedContainer. decode ( [ Int ] . self, forKey: . associatedValue) )
102118 case . doubleArray:
103- self = . doubleArray( try container. decode ( [ Double ] . self, forKey: . doubleArray) )
119+ let nestedContainer = try container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . doubleArray)
120+ self . attributeValue = . doubleArray( try nestedContainer. decode ( [ Double ] . self, forKey: . associatedValue) )
104121 }
105122 }
106123
107124 public func encode( to encoder: Encoder ) throws {
108125
109126 var container = encoder. container ( keyedBy: CodingKeys . self)
110127
111- switch self {
128+ switch self . attributeValue {
112129 case . string( let value) :
113- try container. encode ( value, forKey: . string)
130+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . string)
131+ try nestedContainer. encode ( value, forKey: . associatedValue)
114132 case . bool( let value) :
115- try container. encode ( value, forKey: . bool)
133+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . bool)
134+ try nestedContainer. encode ( value, forKey: . associatedValue)
116135 case . int( let value) :
117- try container. encode ( value, forKey: . int)
136+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . int)
137+ try nestedContainer. encode ( value, forKey: . associatedValue)
118138 case . double( let value) :
119- try container. encode ( value, forKey: . double)
139+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . double)
140+ try nestedContainer. encode ( value, forKey: . associatedValue)
120141 case . stringArray( let value) :
121- try container. encode ( value, forKey: . stringArray)
142+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . stringArray)
143+ try nestedContainer. encode ( value, forKey: . associatedValue)
122144 case . boolArray( let value) :
123- try container. encode ( value, forKey: . boolArray)
145+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . boolArray)
146+ try nestedContainer. encode ( value, forKey: . associatedValue)
124147 case . intArray( let value) :
125- try container. encode ( value, forKey: . intArray)
148+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . intArray)
149+ try nestedContainer. encode ( value, forKey: . associatedValue)
126150 case . doubleArray( let value) :
127- try container. encode ( value, forKey: . doubleArray)
151+ var nestedContainer = container. nestedContainer ( keyedBy: AssociatedValueCodingKeys . self, forKey: . doubleArray)
152+ try nestedContainer. encode ( value, forKey: . associatedValue)
128153 }
129154 }
130155}
156+
157+ #if swift(>=5.5)
158+ // swift 5.5 supports synthesizing Codable for enums with associated values
159+ // see https://github.com/apple/swift-evolution/blob/main/proposals/0295-codable-synthesis-for-enums-with-associated-values.md
160+ extension AttributeValue : Codable { }
161+ #else
162+ // for older swift versions use a forward compatible explicit Codable implementation
163+ extension AttributeValue : Codable {
164+
165+ public init ( from decoder: Decoder ) throws {
166+ let explicitDecoded = AttributeValueExplicitCodable ( from: decoder)
167+
168+ self = explicitDecoded. attributeValue
169+ }
170+
171+ public func encode( to encoder: Encoder ) throws {
172+ let explicitEncoded = AttributeValueExplicitCodable ( attributeValue: self )
173+
174+ explicitEncoded. encode ( to: encoder)
175+ }
176+ }
177+ #endif
0 commit comments