Skip to content

Commit f550ea6

Browse files
authored
Merge pull request #1108 from bubski/codable
2 parents ddcbfec + 5d6db14 commit f550ea6

File tree

11 files changed

+438
-19
lines changed

11 files changed

+438
-19
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@
354354
D51239DF1CD9DA0800D433EE /* CFSocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D88E01BBC9B0300234F36 /* CFSocket.c */; };
355355
D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D512D17B1CD883F00032E6A5 /* TestFileHandle.swift */; };
356356
D5C40F331CDA1D460005690C /* TestNSOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5C40F321CDA1D460005690C /* TestNSOperationQueue.swift */; };
357+
DCA8120B1F046D13000D0C86 /* TestCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA8120A1F046D13000D0C86 /* TestCodable.swift */; };
357358
E1A03F361C4828650023AF4D /* PropertyList-1.0.dtd in Resources */ = {isa = PBXBuildFile; fileRef = E1A03F351C4828650023AF4D /* PropertyList-1.0.dtd */; };
358359
E1A03F381C482C730023AF4D /* NSXMLDTDTestData.xml in Resources */ = {isa = PBXBuildFile; fileRef = E1A03F371C482C730023AF4D /* NSXMLDTDTestData.xml */; };
359360
E1A3726F1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml in Resources */ = {isa = PBXBuildFile; fileRef = E1A3726E1C31EBFB0023AF4D /* NSXMLDocumentTestData.xml */; };
@@ -822,6 +823,7 @@
822823
D512D17B1CD883F00032E6A5 /* TestFileHandle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestFileHandle.swift; sourceTree = "<group>"; };
823824
D5C40F321CDA1D460005690C /* TestNSOperationQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSOperationQueue.swift; sourceTree = "<group>"; };
824825
D834F9931C31C4060023812A /* TestNSOrderedSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSOrderedSet.swift; sourceTree = "<group>"; };
826+
DCA8120A1F046D13000D0C86 /* TestCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCodable.swift; sourceTree = "<group>"; };
825827
DCDBB8321C1768AC00313299 /* TestNSData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSData.swift; sourceTree = "<group>"; };
826828
E1A03F351C4828650023AF4D /* PropertyList-1.0.dtd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "PropertyList-1.0.dtd"; sourceTree = "<group>"; };
827829
E1A03F371C482C730023AF4D /* NSXMLDTDTestData.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = NSXMLDTDTestData.xml; sourceTree = "<group>"; };
@@ -1423,8 +1425,7 @@
14231425
A058C2011E529CF100B07AA1 /* TestMassFormatter.swift */,
14241426
BF8E65301DC3B3CB005AB5C3 /* TestNotification.swift */,
14251427
3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */,
1426-
159884911DCC877700E3314C /* TestNSHTTPCookieStorage.swift */,
1427-
D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
1428+
DCA8120A1F046D13000D0C86 /* TestCodable.swift */,
14281429
C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */,
14291430
EA66F63C1BF1619600136161 /* TestNSArray.swift */,
14301431
294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */,
@@ -2430,6 +2431,7 @@
24302431
5B13B3271C582D4C00651CE2 /* TestNSArray.swift in Sources */,
24312432
5B13B3461C582D4C00651CE2 /* TestProcess.swift in Sources */,
24322433
555683BD1C1250E70041D4C6 /* TestNSUserDefaults.swift in Sources */,
2434+
DCA8120B1F046D13000D0C86 /* TestCodable.swift in Sources */,
24332435
7900433B1CACD33E00ECCBF1 /* TestNSCompoundPredicate.swift in Sources */,
24342436
);
24352437
runOnlyForDeploymentPostprocessing = 0;

Foundation/CGFloat.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,3 +949,35 @@ extension CGFloat : _CVarArgPassedAsDouble, _CVarArgAligned {
949949
return native._cVarArgAlignment
950950
}
951951
}
952+
953+
extension CGFloat : Codable {
954+
@_transparent
955+
public init(from decoder: Decoder) throws {
956+
let container = try decoder.singleValueContainer()
957+
do {
958+
self.native = try container.decode(NativeType.self)
959+
} catch DecodingError.typeMismatch(let type, let context) {
960+
// We may have encoded as a different type on a different platform. A
961+
// strict fixed-format decoder may disallow a conversion, so let's try the
962+
// other type.
963+
do {
964+
if NativeType.self == Float.self {
965+
self.native = NativeType(try container.decode(Double.self))
966+
} else {
967+
self.native = NativeType(try container.decode(Float.self))
968+
}
969+
} catch {
970+
// Failed to decode as the other type, too. This is neither a Float nor
971+
// a Double. Throw the old error; we don't want to clobber the original
972+
// info.
973+
throw DecodingError.typeMismatch(type, context)
974+
}
975+
}
976+
}
977+
978+
@_transparent
979+
public func encode(to encoder: Encoder) throws {
980+
var container = encoder.singleValueContainer()
981+
try container.encode(self.native)
982+
}
983+
}

Foundation/CharacterSet.swift

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===----------------------------------------------------------------------===//
1+
//===----------------------------------------------------------------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -13,7 +13,7 @@
1313
private func _utfRangeToNSRange(_ inRange : Range<UnicodeScalar>) -> NSRange {
1414
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value))
1515
}
16-
16+
1717
private func _utfRangeToNSRange(_ inRange : ClosedRange<UnicodeScalar>) -> NSRange {
1818
return NSMakeRange(Int(inRange.lowerBound.value), Int(inRange.upperBound.value - inRange.lowerBound.value + 1))
1919
}
@@ -57,9 +57,9 @@ internal final class _SwiftNSCharacterSet : NSCharacterSet, _SwiftNativeFoundati
5757
deinit {
5858
releaseWrappedObject()
5959
}
60-
61-
62-
override func copy(with zone: NSZone? = nil) -> Any {
60+
61+
62+
override func copy(with zone: NSZone? = nil) -> Any {
6363
return _mapUnmanaged { $0.copy(with: zone) }
6464
}
6565

@@ -74,23 +74,23 @@ internal final class _SwiftNSCharacterSet : NSCharacterSet, _SwiftNativeFoundati
7474
override var bitmapRepresentation: Data {
7575
return _mapUnmanaged { $0.bitmapRepresentation }
7676
}
77-
77+
7878
override var inverted : CharacterSet {
7979
return _mapUnmanaged { $0.inverted }
8080
}
81-
81+
8282
override func hasMemberInPlane(_ thePlane: UInt8) -> Bool {
8383
return _mapUnmanaged {$0.hasMemberInPlane(thePlane) }
8484
}
85-
85+
8686
override func characterIsMember(_ member: unichar) -> Bool {
8787
return _mapUnmanaged { $0.characterIsMember(member) }
8888
}
89-
89+
9090
override func longCharacterIsMember(_ member: UInt32) -> Bool {
9191
return _mapUnmanaged { $0.longCharacterIsMember(member) }
9292
}
93-
93+
9494
override func isSuperset(of other: CharacterSet) -> Bool {
9595
return _mapUnmanaged { $0.isSuperset(of: other) }
9696
}
@@ -367,7 +367,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
367367
// -----
368368
// MARK: -
369369
// MARK: SetAlgebraType
370-
370+
371371
/// Insert a `UnicodeScalar` representation of a character into the `CharacterSet`.
372372
///
373373
/// `UnicodeScalar` values are available on `Swift.String.UnicodeScalarView`.
@@ -441,17 +441,17 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
441441
$0.formIntersection(with: other)
442442
}
443443
}
444-
444+
445445
/// Returns a `CharacterSet` created by removing elements in `other` from `self`.
446446
public func subtracting(_ other: CharacterSet) -> CharacterSet {
447447
return intersection(other.inverted)
448448
}
449-
449+
450450
/// Sets the value to a `CharacterSet` created by removing elements in `other` from `self`.
451451
public mutating func subtract(_ other: CharacterSet) {
452452
self = subtracting(other)
453453
}
454-
454+
455455
/// Returns an exclusive or of the `CharacterSet` with another `CharacterSet`.
456456
public func symmetricDifference(_ other: CharacterSet) -> CharacterSet {
457457
return union(other).subtracting(intersection(other))
@@ -466,7 +466,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
466466
public func isSuperset(of other: CharacterSet) -> Bool {
467467
return _mapUnmanaged { $0.isSuperset(of: other) }
468468
}
469-
469+
470470
/// Returns true if the two `CharacterSet`s are equal.
471471
public static func ==(lhs : CharacterSet, rhs: CharacterSet) -> Bool {
472472
return lhs._wrapped.isEqual(rhs._bridgeToObjectiveC()) // TODO: mlehew - as NSCharacterSet
@@ -475,7 +475,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
475475

476476

477477
// MARK: Objective-C Bridging
478-
extension CharacterSet : _ObjectTypeBridgeable {
478+
extension CharacterSet : _ObjectTypeBridgeable {
479479
public static func _isBridgedToObjectiveC() -> Bool {
480480
return true
481481
}

Foundation/IndexPath.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,4 +851,3 @@ extension IndexPath : Codable {
851851
}
852852
}
853853
}
854-

Foundation/Locale.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,20 @@ extension Locale : _ObjectTypeBridgeable {
466466
return result!
467467
}
468468
}
469+
470+
extension Locale : Codable {
471+
private enum CodingKeys : Int, CodingKey {
472+
case identifier
473+
}
474+
475+
public init(from decoder: Decoder) throws {
476+
let container = try decoder.container(keyedBy: CodingKeys.self)
477+
let identifier = try container.decode(String.self, forKey: .identifier)
478+
self.init(identifier: identifier)
479+
}
480+
481+
public func encode(to encoder: Encoder) throws {
482+
var container = encoder.container(keyedBy: CodingKeys.self)
483+
try container.encode(self.identifier, forKey: .identifier)
484+
}
485+
}

Foundation/NSAffineTransform.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,25 @@ extension NSAffineTransform : _StructTypeBridgeable {
455455
return AffineTransform._unconditionallyBridgeFromObjectiveC(self)
456456
}
457457
}
458+
459+
extension AffineTransform : Codable {
460+
public init(from decoder: Decoder) throws {
461+
var container = try decoder.unkeyedContainer()
462+
m11 = try container.decode(CGFloat.self)
463+
m12 = try container.decode(CGFloat.self)
464+
m21 = try container.decode(CGFloat.self)
465+
m22 = try container.decode(CGFloat.self)
466+
tX = try container.decode(CGFloat.self)
467+
tY = try container.decode(CGFloat.self)
468+
}
469+
470+
public func encode(to encoder: Encoder) throws {
471+
var container = encoder.unkeyedContainer()
472+
try container.encode(self.m11)
473+
try container.encode(self.m12)
474+
try container.encode(self.m21)
475+
try container.encode(self.m22)
476+
try container.encode(self.tX)
477+
try container.encode(self.tY)
478+
}
479+
}

Foundation/NSDecimal.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,3 +2087,58 @@ extension Scanner {
20872087
return result
20882088
}
20892089
}
2090+
2091+
extension Decimal : Codable {
2092+
private enum CodingKeys : Int, CodingKey {
2093+
case exponent
2094+
case length
2095+
case isNegative
2096+
case isCompact
2097+
case mantissa
2098+
}
2099+
2100+
public init(from decoder: Decoder) throws {
2101+
let container = try decoder.container(keyedBy: CodingKeys.self)
2102+
let exponent = try container.decode(CInt.self, forKey: .exponent)
2103+
let length = try container.decode(CUnsignedInt.self, forKey: .length)
2104+
let isNegative = try container.decode(Bool.self, forKey: .isNegative)
2105+
let isCompact = try container.decode(Bool.self, forKey: .isCompact)
2106+
2107+
var mantissaContainer = try container.nestedUnkeyedContainer(forKey: .mantissa)
2108+
var mantissa: (CUnsignedShort, CUnsignedShort, CUnsignedShort, CUnsignedShort,
2109+
CUnsignedShort, CUnsignedShort, CUnsignedShort, CUnsignedShort) = (0,0,0,0,0,0,0,0)
2110+
mantissa.0 = try mantissaContainer.decode(CUnsignedShort.self)
2111+
mantissa.1 = try mantissaContainer.decode(CUnsignedShort.self)
2112+
mantissa.2 = try mantissaContainer.decode(CUnsignedShort.self)
2113+
mantissa.3 = try mantissaContainer.decode(CUnsignedShort.self)
2114+
mantissa.4 = try mantissaContainer.decode(CUnsignedShort.self)
2115+
mantissa.5 = try mantissaContainer.decode(CUnsignedShort.self)
2116+
mantissa.6 = try mantissaContainer.decode(CUnsignedShort.self)
2117+
mantissa.7 = try mantissaContainer.decode(CUnsignedShort.self)
2118+
2119+
self.init(_exponent: exponent,
2120+
_length: length,
2121+
_isNegative: CUnsignedInt(isNegative ? 1 : 0),
2122+
_isCompact: CUnsignedInt(isCompact ? 1 : 0),
2123+
_reserved: 0,
2124+
_mantissa: mantissa)
2125+
}
2126+
2127+
public func encode(to encoder: Encoder) throws {
2128+
var container = encoder.container(keyedBy: CodingKeys.self)
2129+
try container.encode(_exponent, forKey: .exponent)
2130+
try container.encode(_length, forKey: .length)
2131+
try container.encode(_isNegative == 0 ? false : true, forKey: .isNegative)
2132+
try container.encode(_isCompact == 0 ? false : true, forKey: .isCompact)
2133+
2134+
var mantissaContainer = container.nestedUnkeyedContainer(forKey: .mantissa)
2135+
try mantissaContainer.encode(_mantissa.0)
2136+
try mantissaContainer.encode(_mantissa.1)
2137+
try mantissaContainer.encode(_mantissa.2)
2138+
try mantissaContainer.encode(_mantissa.3)
2139+
try mantissaContainer.encode(_mantissa.4)
2140+
try mantissaContainer.encode(_mantissa.5)
2141+
try mantissaContainer.encode(_mantissa.6)
2142+
try mantissaContainer.encode(_mantissa.7)
2143+
}
2144+
}

Foundation/PersonNameComponents.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,36 @@ extension NSPersonNameComponents : _HasCustomAnyHashableRepresentation {
137137
return AnyHashable(self._bridgeToSwift())
138138
}
139139
}
140+
141+
extension PersonNameComponents : Codable {
142+
private enum CodingKeys : Int, CodingKey {
143+
case namePrefix
144+
case givenName
145+
case middleName
146+
case familyName
147+
case nameSuffix
148+
case nickname
149+
}
150+
151+
public init(from decoder: Decoder) throws {
152+
self.init()
153+
154+
let container = try decoder.container(keyedBy: CodingKeys.self)
155+
self.namePrefix = try container.decodeIfPresent(String.self, forKey: .namePrefix)
156+
self.givenName = try container.decodeIfPresent(String.self, forKey: .givenName)
157+
self.middleName = try container.decodeIfPresent(String.self, forKey: .middleName)
158+
self.familyName = try container.decodeIfPresent(String.self, forKey: .familyName)
159+
self.nameSuffix = try container.decodeIfPresent(String.self, forKey: .nameSuffix)
160+
self.nickname = try container.decodeIfPresent(String.self, forKey: .nickname)
161+
}
162+
163+
public func encode(to encoder: Encoder) throws {
164+
var container = encoder.container(keyedBy: CodingKeys.self)
165+
if let np = self.namePrefix { try container.encode(np, forKey: .namePrefix) }
166+
if let gn = self.givenName { try container.encode(gn, forKey: .givenName) }
167+
if let mn = self.middleName { try container.encode(mn, forKey: .middleName) }
168+
if let fn = self.familyName { try container.encode(fn, forKey: .familyName) }
169+
if let ns = self.nameSuffix { try container.encode(ns, forKey: .nameSuffix) }
170+
if let nn = self.nickname { try container.encode(nn, forKey: .nickname) }
171+
}
172+
}

Foundation/UUID.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,21 @@ extension NSUUID : _HasCustomAnyHashableRepresentation {
163163
}
164164
}
165165

166+
extension UUID : Codable {
167+
public init(from decoder: Decoder) throws {
168+
let container = try decoder.singleValueContainer()
169+
let uuidString = try container.decode(String.self)
170+
171+
guard let uuid = UUID(uuidString: uuidString) else {
172+
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath,
173+
debugDescription: "Attempted to decode UUID from invalid UUID string."))
174+
}
175+
176+
self = uuid
177+
}
178+
179+
public func encode(to encoder: Encoder) throws {
180+
var container = encoder.singleValueContainer()
181+
try container.encode(self.uuidString)
182+
}
183+
}

0 commit comments

Comments
 (0)