Skip to content

Commit eac219a

Browse files
committed
JSONEncoder implemented
1 parent d8f78f9 commit eac219a

File tree

12 files changed

+3860
-6
lines changed

12 files changed

+3860
-6
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
231503DB1D8AEE5D0061694D /* TestNSDecimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */; };
1414
294E3C1D1CC5E19300E4F44C /* TestNSAttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */; };
1515
2EBE67A51C77BF0E006583D5 /* TestNSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */; };
16+
3E8583B31EF5B6B600174E94 /* ConsistentCasting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E8583B21EF5B6B600174E94 /* ConsistentCasting.swift */; };
17+
3E8583B41EF5BFA700174E94 /* ConsistentCasting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E8583B21EF5B6B600174E94 /* ConsistentCasting.swift */; };
18+
3EA9D66E1EF050C800B362D6 /* TestCastingUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA9D66D1EF050C800B362D6 /* TestCastingUtils.swift */; };
19+
3EA9D6701EF0532D00B362D6 /* TestJSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */; };
20+
3EDCE50C1EF04D8100C2EC04 /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCE5051EF04D8100C2EC04 /* Codable.swift */; };
21+
3EDCE5101EF04D8100C2EC04 /* JSONEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCE5091EF04D8100C2EC04 /* JSONEncoder.swift */; };
1622
528776141BF2629700CB0090 /* FoundationErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522C253A1BF16E1600804FC6 /* FoundationErrors.swift */; };
1723
528776191BF27D9500CB0090 /* Test.plist in Resources */ = {isa = PBXBuildFile; fileRef = 528776181BF27D9500CB0090 /* Test.plist */; };
1824
555683BD1C1250E70041D4C6 /* TestNSUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 555683BC1C1250E70041D4C6 /* TestNSUserDefaults.swift */; };
@@ -482,6 +488,11 @@
482488
231503DA1D8AEE5D0061694D /* TestNSDecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDecimal.swift; sourceTree = "<group>"; };
483489
294E3C1C1CC5E19300E4F44C /* TestNSAttributedString.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSAttributedString.swift; sourceTree = "<group>"; };
484490
2EBE67A31C77BF05006583D5 /* TestNSDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDateFormatter.swift; sourceTree = "<group>"; };
491+
3E8583B21EF5B6B600174E94 /* ConsistentCasting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsistentCasting.swift; sourceTree = "<group>"; };
492+
3EA9D66D1EF050C800B362D6 /* TestCastingUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCastingUtils.swift; sourceTree = "<group>"; };
493+
3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestJSONEncoder.swift; sourceTree = "<group>"; };
494+
3EDCE5051EF04D8100C2EC04 /* Codable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Codable.swift; sourceTree = "<group>"; };
495+
3EDCE5091EF04D8100C2EC04 /* JSONEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONEncoder.swift; sourceTree = "<group>"; };
485496
400E22641C1A4E58007C5933 /* TestProcessInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestProcessInfo.swift; sourceTree = "<group>"; };
486497
4AE109261C17CCBF007367B5 /* TestNSIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSIndexPath.swift; sourceTree = "<group>"; };
487498
4DC1D07F1C12EEEF00B5948A /* TestNSPipe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSPipe.swift; sourceTree = "<group>"; };
@@ -959,6 +970,16 @@
959970
/* End PBXFrameworksBuildPhase section */
960971

961972
/* Begin PBXGroup section */
973+
3EDCE5121EF04D8600C2EC04 /* JSONEncoder */ = {
974+
isa = PBXGroup;
975+
children = (
976+
3EDCE5051EF04D8100C2EC04 /* Codable.swift */,
977+
3EDCE5091EF04D8100C2EC04 /* JSONEncoder.swift */,
978+
3E8583B21EF5B6B600174E94 /* ConsistentCasting.swift */,
979+
);
980+
name = JSONEncoder;
981+
sourceTree = "<group>";
982+
};
962983
5B1FD9C71D6D162D0080E83C /* Session */ = {
963984
isa = PBXGroup;
964985
children = (
@@ -1395,6 +1416,8 @@
13951416
EA66F65A1BF1976100136161 /* Tests */ = {
13961417
isa = PBXGroup;
13971418
children = (
1419+
3EA9D66F1EF0532D00B362D6 /* TestJSONEncoder.swift */,
1420+
3EA9D66D1EF050C800B362D6 /* TestCastingUtils.swift */,
13981421
159884911DCC877700E3314C /* TestNSHTTPCookieStorage.swift */,
13991422
D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
14001423
C93559281C12C49F009FD6A9 /* TestNSAffineTransform.swift */,
@@ -1593,6 +1616,7 @@
15931616
EAB57B6C1BD1A852004AC5C5 /* Serialization */ = {
15941617
isa = PBXGroup;
15951618
children = (
1619+
3EDCE5121EF04D8600C2EC04 /* JSONEncoder */,
15961620
EADE0B641BD15DFF00C49C64 /* NSJSONSerialization.swift */,
15971621
EADE0B651BD15DFF00C49C64 /* NSKeyedArchiver.swift */,
15981622
D3BCEB9F1C2F6DDB00295652 /* NSKeyedCoderOldStyleArray.swift */,
@@ -2120,6 +2144,7 @@
21202144
EADE0B951BD15DFF00C49C64 /* NSDateComponentsFormatter.swift in Sources */,
21212145
EADE0BBD1BD15E0000C49C64 /* NSURLCredential.swift in Sources */,
21222146
EADE0BCA1BD15E0000C49C64 /* NSXMLElement.swift in Sources */,
2147+
3E8583B31EF5B6B600174E94 /* ConsistentCasting.swift in Sources */,
21232148
EADE0BA21BD15E0000C49C64 /* NSJSONSerialization.swift in Sources */,
21242149
5BF7AEBA1BCD51F9008F214A /* NSString.swift in Sources */,
21252150
5BF7AEB81BCD51F9008F214A /* NSRange.swift in Sources */,
@@ -2141,6 +2166,7 @@
21412166
D3E8D6D11C367AB600295652 /* NSSpecialValue.swift in Sources */,
21422167
EAB57B721BD1C7A5004AC5C5 /* NSPortMessage.swift in Sources */,
21432168
5BD31D201D5CE8C400563814 /* Bridging.swift in Sources */,
2169+
3EDCE50C1EF04D8100C2EC04 /* Codable.swift in Sources */,
21442170
EADE0BBB1BD15E0000C49C64 /* NSURLAuthenticationChallenge.swift in Sources */,
21452171
EADE0BA11BD15DFF00C49C64 /* NSIndexSet.swift in Sources */,
21462172
5BF7AEA91BCD51F9008F214A /* NSDate.swift in Sources */,
@@ -2156,6 +2182,7 @@
21562182
5BD31D411D5D1BC300563814 /* Set.swift in Sources */,
21572183
5BD31D241D5CECC400563814 /* Array.swift in Sources */,
21582184
5BF7AEBC1BCD51F9008F214A /* Thread.swift in Sources */,
2185+
3EDCE5101EF04D8100C2EC04 /* JSONEncoder.swift in Sources */,
21592186
D31302011C30CEA900295652 /* NSConcreteValue.swift in Sources */,
21602187
5BF7AEA81BCD51F9008F214A /* NSData.swift in Sources */,
21612188
5B424C761D0B6E5B007B39C8 /* IndexPath.swift in Sources */,
@@ -2364,6 +2391,7 @@
23642391
5B13B3301C582D4C00651CE2 /* TestNSHTTPCookie.swift in Sources */,
23652392
5B13B3361C582D4C00651CE2 /* TestNSLocale.swift in Sources */,
23662393
5B13B3391C582D4C00651CE2 /* TestNSNull.swift in Sources */,
2394+
3EA9D66E1EF050C800B362D6 /* TestCastingUtils.swift in Sources */,
23672395
BD8042161E09857800487EB8 /* TestNSLengthFormatter.swift in Sources */,
23682396
5B13B3421C582D4C00651CE2 /* TestNSRunLoop.swift in Sources */,
23692397
5B13B34E1C582D4C00651CE2 /* TestNSXMLDocument.swift in Sources */,
@@ -2396,11 +2424,13 @@
23962424
5B13B3371C582D4C00651CE2 /* TestNSNotificationCenter.swift in Sources */,
23972425
5B13B3251C582D4700651CE2 /* main.swift in Sources */,
23982426
5B1FD9E31D6D17B80080E83C /* TestNSURLSession.swift in Sources */,
2427+
3EA9D6701EF0532D00B362D6 /* TestJSONEncoder.swift in Sources */,
23992428
D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */,
24002429
D4FE895B1D703D1100DA7986 /* TestURLRequest.swift in Sources */,
24012430
5B13B33A1C582D4C00651CE2 /* TestNSNumber.swift in Sources */,
24022431
5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
24032432
5B13B3311C582D4C00651CE2 /* TestNSIndexPath.swift in Sources */,
2433+
3E8583B41EF5BFA700174E94 /* ConsistentCasting.swift in Sources */,
24042434
5B13B3271C582D4C00651CE2 /* TestNSArray.swift in Sources */,
24052435
5B13B3461C582D4C00651CE2 /* TestProcess.swift in Sources */,
24062436
555683BD1C1250E70041D4C6 /* TestNSUserDefaults.swift in Sources */,
@@ -2778,7 +2808,7 @@
27782808
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
27792809
LIBRARY_SEARCH_PATHS = "$(inherited)";
27802810
MACH_O_TYPE = mh_execute;
2781-
OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 3";
2811+
OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 3 -DTEST_TARGET";
27822812
PRODUCT_BUNDLE_IDENTIFIER = org.swift.TestFoundation;
27832813
PRODUCT_NAME = "$(TARGET_NAME)";
27842814
SKIP_INSTALL = YES;
@@ -2804,7 +2834,7 @@
28042834
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
28052835
LIBRARY_SEARCH_PATHS = "$(inherited)";
28062836
MACH_O_TYPE = mh_execute;
2807-
OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 3";
2837+
OTHER_SWIFT_FLAGS = "-DDEPLOYMENT_ENABLE_LIBDISPATCH -swift-version 3 -DTEST_TARGET";
28082838
PRODUCT_BUNDLE_IDENTIFIER = org.swift.TestFoundation;
28092839
PRODUCT_NAME = "$(TARGET_NAME)";
28102840
SKIP_INSTALL = YES;

Foundation/Codable.swift

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
//===----------------------------------------------------------------------===//
11+
// Errors
12+
//===----------------------------------------------------------------------===//
13+
14+
// Adding the following extensions to EncodingError and DecodingError allows them to bridge to NSErrors implicitly.
15+
16+
fileprivate let NSCodingPathErrorKey = "NSCodingPath"
17+
fileprivate let NSDebugDescriptionErrorKey = "NSDebugDescription"
18+
19+
extension EncodingError : CustomNSError {
20+
public static var errorDomain: String = NSCocoaErrorDomain
21+
22+
public var errorCode: Int {
23+
switch self {
24+
case .invalidValue(_, _): return CocoaError.coderInvalidValue.rawValue
25+
}
26+
}
27+
28+
public var errorUserInfo: [String : Any] {
29+
let context: Context
30+
switch self {
31+
case .invalidValue(_, let c): context = c
32+
}
33+
34+
return [NSCodingPathErrorKey: context.codingPath,
35+
NSDebugDescriptionErrorKey: context.debugDescription]
36+
}
37+
}
38+
39+
extension DecodingError : CustomNSError {
40+
public static var errorDomain: String = NSCocoaErrorDomain
41+
42+
public var errorCode: Int {
43+
switch self {
44+
case .valueNotFound(_, _): fallthrough
45+
case .keyNotFound(_, _):
46+
return CocoaError.coderValueNotFound.rawValue
47+
48+
case .typeMismatch(_, _): fallthrough
49+
case .dataCorrupted(_):
50+
return CocoaError.coderReadCorrupt.rawValue
51+
}
52+
}
53+
54+
public var errorUserInfo: [String : Any] {
55+
let context: Context
56+
switch self {
57+
case .typeMismatch(_, let c): context = c
58+
case .valueNotFound(_, let c): context = c
59+
case .keyNotFound(_, let c): context = c
60+
case .dataCorrupted(let c): context = c
61+
}
62+
63+
return [NSCodingPathErrorKey: context.codingPath,
64+
NSDebugDescriptionErrorKey: context.debugDescription]
65+
}
66+
}
67+
68+
//===----------------------------------------------------------------------===//
69+
// Error Utilities
70+
//===----------------------------------------------------------------------===//
71+
72+
internal extension DecodingError {
73+
/// Returns a `.typeMismatch` error describing the expected type.
74+
///
75+
/// - parameter path: The path of `CodingKey`s taken to decode a value of this type.
76+
/// - parameter expectation: The type expected to be encountered.
77+
/// - parameter reality: The value that was encountered instead of the expected type.
78+
/// - returns: A `DecodingError` with the appropriate path and debug description.
79+
internal static func _typeMismatch(at path: [CodingKey?], expectation: Any.Type, reality: Any) -> DecodingError {
80+
let description = "Expected to decode \(expectation) but found \(_typeDescription(of: reality)) instead."
81+
return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description))
82+
}
83+
84+
/// Returns a description of the type of `value` appropriate for an error message.
85+
///
86+
/// - parameter value: The value whose type to describe.
87+
/// - returns: A string describing `value`.
88+
/// - precondition: `value` is one of the types below.
89+
fileprivate static func _typeDescription(of value: Any) -> String {
90+
if value is NSNull {
91+
return "a null value"
92+
} else if value is NSNumber /* FIXME: If swift-corelibs-foundation isn't updated to use NSNumber, this check will be necessary: || value is Int || value is Double */ {
93+
return "a number"
94+
} else if value is String {
95+
return "a string/data"
96+
} else if value is [Any] {
97+
return "an array"
98+
} else if value is [String : Any] {
99+
return "a dictionary"
100+
} else {
101+
// This should never happen -- we somehow have a non-JSON type here.
102+
preconditionFailure("Invalid storage type \(type(of: value)).")
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)