From 2236c63bae71f339b2fc6cef00332ae3fbdab2b7 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Sun, 29 Oct 2017 03:25:38 +0100 Subject: [PATCH 1/4] Remove as much as possible --- Decodable.xcodeproj/project.pbxproj | 72 --------- Sources/Castable.swift | 112 -------------- Sources/Decodable.swift | 58 ------- Sources/Decoders.swift | 64 -------- Sources/DecodingError.swift | 143 ------------------ Sources/KeyPath.swift | 56 ------- Sources/NSValueCastable.swift | 59 -------- Sources/Operators.swift | 34 ----- Sources/OptionalKeyPath.swift | 91 ----------- Sources/Parse.swift | 91 ----------- Sources/Playground.playground/Contents.swift | 4 - .../contents.xcplayground | 4 - Sources/RawRepresentableDecodable.swift | 23 +-- 13 files changed, 12 insertions(+), 799 deletions(-) delete mode 100644 Sources/Castable.swift delete mode 100644 Sources/Decoders.swift delete mode 100644 Sources/DecodingError.swift delete mode 100644 Sources/KeyPath.swift delete mode 100644 Sources/NSValueCastable.swift delete mode 100644 Sources/OptionalKeyPath.swift delete mode 100644 Sources/Parse.swift delete mode 100644 Sources/Playground.playground/Contents.swift delete mode 100644 Sources/Playground.playground/contents.xcplayground diff --git a/Decodable.xcodeproj/project.pbxproj b/Decodable.xcodeproj/project.pbxproj index aa0439b..073d91e 100644 --- a/Decodable.xcodeproj/project.pbxproj +++ b/Decodable.xcodeproj/project.pbxproj @@ -10,8 +10,6 @@ 17FB81011B530FED0012F106 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17FB80F71B530FED0012F106 /* Decodable.framework */; }; 17FB810E1B5311840012F106 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; 17FB810F1B5311870012F106 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; - 57FCDE5B1BA283C900130C48 /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; }; - 57FCDE5C1BA283C900130C48 /* Parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFAB8111B7CFA9500E2D724 /* Parse.swift */; }; 57FCDE5D1BA283C900130C48 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; 57FCDE5E1BA283C900130C48 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; 651A8C971C29AC5F00DE4D53 /* RawRepresentableDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */; }; @@ -24,20 +22,8 @@ 8F0062401C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; 8F0062411C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; 8F0062421C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; - 8F012EF51BB5A920007D0B5C /* Castable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F012EF41BB5A920007D0B5C /* Castable.swift */; }; - 8F012EF61BB5A920007D0B5C /* Castable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F012EF41BB5A920007D0B5C /* Castable.swift */; }; - 8F012EF71BB5A920007D0B5C /* Castable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F012EF41BB5A920007D0B5C /* Castable.swift */; }; - 8F012EF81BB5A928007D0B5C /* Castable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F012EF41BB5A920007D0B5C /* Castable.swift */; }; - 8F3E459A1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */; }; - 8F3E459B1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */; }; - 8F3E459C1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */; }; - 8F3E459D1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */; }; 8F3E459F1D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F3E45A01D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; - 8F3E45A41D327E4500FB71FC /* Decoders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45A31D327E4500FB71FC /* Decoders.swift */; }; - 8F3E45A51D327E4500FB71FC /* Decoders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45A31D327E4500FB71FC /* Decoders.swift */; }; - 8F3E45A61D327E4500FB71FC /* Decoders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45A31D327E4500FB71FC /* Decoders.swift */; }; - 8F3E45A71D327E4500FB71FC /* Decoders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45A31D327E4500FB71FC /* Decoders.swift */; }; 8F3E45B81D32884700FB71FC /* Documentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45AE1D32853F00FB71FC /* Documentation.swift */; }; 8F4453EF1D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; 8F4453F01D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; @@ -47,33 +33,20 @@ 8F53521E1BE4112900E3563A /* DictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F53521C1BE4112900E3563A /* DictionaryTests.swift */; }; 8F6FCF5F1D4B39FC00838CE4 /* DynamicDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F6FCF5E1D4B39FC00838CE4 /* DynamicDecodableTests.swift */; }; 8F6FCF601D4B39FC00838CE4 /* DynamicDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F6FCF5E1D4B39FC00838CE4 /* DynamicDecodableTests.swift */; }; - 8F72DC561C3CB8C500A39E10 /* NSValueCastable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */; }; - 8F72DC571C3CB8C800A39E10 /* NSValueCastable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */; }; - 8F72DC581C3CB8C900A39E10 /* NSValueCastable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */; }; - 8F72DC591C3CB8C900A39E10 /* NSValueCastable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */; }; 8F84E70F1C3CB92D001EA4CE /* NSValueDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F84E70E1C3CB92D001EA4CE /* NSValueDecodableTests.swift */; }; 8F84E7101C3CB92D001EA4CE /* NSValueDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F84E70E1C3CB92D001EA4CE /* NSValueDecodableTests.swift */; }; 8F85E7781E13DA16000D6989 /* NSNullTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F85E7771E13DA16000D6989 /* NSNullTests.swift */; }; 8F85E7791E13DA16000D6989 /* NSNullTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F85E7771E13DA16000D6989 /* NSNullTests.swift */; }; 8F87BCBB1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; }; 8F87BCBC1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; }; - 8F87BCC41B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; }; - 8F87BCC51B592F0E00E53A8C /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; }; 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; 8FA733591D328D13003A90A7 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45AF1D32853F00FB71FC /* Header.swift */; }; - 8FB48ECA1D306C4700BC50A1 /* KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */; }; - 8FB48ECB1D306C4700BC50A1 /* KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */; }; - 8FB48ECC1D306C4700BC50A1 /* KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */; }; - 8FB48ECD1D306C4700BC50A1 /* KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */; }; 8FD3D92F1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FD3D92E1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift */; }; 8FD3D9301C270A2D00D1AF4E /* MissingKeyOperatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FD3D92E1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift */; }; 8FE7B5661B4C9FB900837609 /* Decodable.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FE7B5651B4C9FB900837609 /* Decodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8FE7B56D1B4C9FB900837609 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8FE7B5621B4C9FB900837609 /* Decodable.framework */; }; 8FE7B5721B4C9FB900837609 /* DecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */; }; 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; - 8FFAB8121B7CFA9500E2D724 /* Parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFAB8111B7CFA9500E2D724 /* Parse.swift */; }; - 8FFAB8131B7CFA9500E2D724 /* Parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFAB8111B7CFA9500E2D724 /* Parse.swift */; }; - 8FFAB8141B7CFA9500E2D724 /* Parse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FFAB8111B7CFA9500E2D724 /* Parse.swift */; }; 9E2DA75C1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */; }; 9E2DA75D1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */; }; 9E2DA75F1CBC784700CAF3DF /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75E1CBC784700CAF3DF /* Vehicle.swift */; }; @@ -82,7 +55,6 @@ 9E2DA7661CBC802200CAF3DF /* Vehicle.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E2DA7641CBC802200CAF3DF /* Vehicle.json */; }; D0DC54771B78150900F79CB0 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; D0DC54781B78150900F79CB0 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; - D0DC547A1B78150900F79CB0 /* DecodingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */; }; FF0060981B5453C600D8CB77 /* DecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */; }; FF00609E1B5454F400D8CB77 /* DecodableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF00609D1B5454F400D8CB77 /* DecodableExtensionTests.swift */; }; FF00609F1B5454F400D8CB77 /* DecodableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF00609D1B5454F400D8CB77 /* DecodableExtensionTests.swift */; }; @@ -125,24 +97,17 @@ 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodable.swift; sourceTree = ""; }; 8F00623E1C81EF61007BCF48 /* Overloads.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Overloads.swift; sourceTree = ""; }; 8F0062481C81F4A2007BCF48 /* Generator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Generator.swift; sourceTree = ""; }; - 8F012EEF1BB414D4007D0B5C /* Playground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground.playground; sourceTree = ""; }; - 8F012EF41BB5A920007D0B5C /* Castable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Castable.swift; sourceTree = ""; }; - 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalKeyPath.swift; sourceTree = ""; }; 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPathTests.swift; sourceTree = ""; }; - 8F3E45A31D327E4500FB71FC /* Decoders.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decoders.swift; sourceTree = ""; }; 8F3E45AE1D32853F00FB71FC /* Documentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Documentation.swift; sourceTree = ""; }; 8F3E45AF1D32853F00FB71FC /* Header.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; 8F4453EE1D369FF200C19099 /* ParseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseTests.swift; sourceTree = ""; }; 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = ""; }; 8F53521C1BE4112900E3563A /* DictionaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryTests.swift; sourceTree = ""; }; 8F6FCF5E1D4B39FC00838CE4 /* DynamicDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicDecodableTests.swift; sourceTree = ""; }; - 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSValueCastable.swift; sourceTree = ""; }; 8F84E70E1C3CB92D001EA4CE /* NSValueDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSValueDecodableTests.swift; sourceTree = ""; }; 8F85E7771E13DA16000D6989 /* NSNullTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNullTests.swift; sourceTree = ""; }; 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorPathTests.swift; sourceTree = ""; }; - 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodingError.swift; sourceTree = ""; }; 8F956D1E1B4D6FF700243072 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPath.swift; sourceTree = ""; }; 8FD3D92E1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MissingKeyOperatorTests.swift; sourceTree = ""; }; 8FE7B5621B4C9FB900837609 /* Decodable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Decodable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8FE7B5651B4C9FB900837609 /* Decodable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decodable.h; sourceTree = ""; }; @@ -151,7 +116,6 @@ 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodableTests.swift; sourceTree = ""; }; 8FE7B5731B4C9FB900837609 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8FE7B57C1B4CA01400837609 /* Decodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decodable.swift; sourceTree = ""; }; - 8FFAB8111B7CFA9500E2D724 /* Parse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parse.swift; sourceTree = ""; }; 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodeAsOneOfTests.swift; sourceTree = ""; }; 9E2DA75E1CBC784700CAF3DF /* Vehicle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = ""; }; 9E2DA7641CBC802200CAF3DF /* Vehicle.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Vehicle.json; path = JSONExamples/Vehicle.json; sourceTree = ""; }; @@ -259,18 +223,10 @@ isa = PBXGroup; children = ( 8FE7B5651B4C9FB900837609 /* Decodable.h */, - 8F012EEF1BB414D4007D0B5C /* Playground.playground */, 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */, - 8F72DC551C3CB8C500A39E10 /* NSValueCastable.swift */, - 8F3E45A31D327E4500FB71FC /* Decoders.swift */, - 8FB48EC91D306C4700BC50A1 /* KeyPath.swift */, - 8F3E45991D31362B00FB71FC /* OptionalKeyPath.swift */, 8F956D1E1B4D6FF700243072 /* Operators.swift */, 8F00623E1C81EF61007BCF48 /* Overloads.swift */, 8FE7B57C1B4CA01400837609 /* Decodable.swift */, - 8F012EF41BB5A920007D0B5C /* Castable.swift */, - 8FFAB8111B7CFA9500E2D724 /* Parse.swift */, - 8F87BCC31B592F0E00E53A8C /* DecodingError.swift */, 8FE7B5671B4C9FB900837609 /* Info.plist */, ); name = Decodable; @@ -629,17 +585,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8F87BCC51B592F0E00E53A8C /* DecodingError.swift in Sources */, - 8FFAB8131B7CFA9500E2D724 /* Parse.swift in Sources */, - 8F012EF61BB5A920007D0B5C /* Castable.swift in Sources */, - 8FB48ECB1D306C4700BC50A1 /* KeyPath.swift in Sources */, 17FB810E1B5311840012F106 /* Decodable.swift in Sources */, 17FB810F1B5311870012F106 /* Operators.swift in Sources */, - 8F3E459B1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */, 8F0062401C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B11C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, - 8F72DC571C3CB8C800A39E10 /* NSValueCastable.swift in Sources */, - 8F3E45A51D327E4500FB71FC /* Decoders.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -670,17 +619,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 57FCDE5B1BA283C900130C48 /* DecodingError.swift in Sources */, - 57FCDE5C1BA283C900130C48 /* Parse.swift in Sources */, - 8F012EF81BB5A928007D0B5C /* Castable.swift in Sources */, - 8FB48ECD1D306C4700BC50A1 /* KeyPath.swift in Sources */, 57FCDE5D1BA283C900130C48 /* Decodable.swift in Sources */, 57FCDE5E1BA283C900130C48 /* Operators.swift in Sources */, - 8F3E459D1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */, 8F0062421C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B31C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, - 8F72DC591C3CB8C900A39E10 /* NSValueCastable.swift in Sources */, - 8F3E45A71D327E4500FB71FC /* Decoders.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -688,19 +630,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8F87BCC41B592F0E00E53A8C /* DecodingError.swift in Sources */, 8FA733591D328D13003A90A7 /* Header.swift in Sources */, - 8FFAB8121B7CFA9500E2D724 /* Parse.swift in Sources */, - 8F012EF51BB5A920007D0B5C /* Castable.swift in Sources */, - 8FB48ECA1D306C4700BC50A1 /* KeyPath.swift in Sources */, 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */, - 8F72DC561C3CB8C500A39E10 /* NSValueCastable.swift in Sources */, - 8F3E459A1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */, 8F00623F1C81EF61007BCF48 /* Overloads.swift in Sources */, 8F3E45B81D32884700FB71FC /* Documentation.swift in Sources */, 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */, 65DB18B01C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, - 8F3E45A41D327E4500FB71FC /* Decoders.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -731,17 +666,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D0DC547A1B78150900F79CB0 /* DecodingError.swift in Sources */, - 8FFAB8141B7CFA9500E2D724 /* Parse.swift in Sources */, - 8F012EF71BB5A920007D0B5C /* Castable.swift in Sources */, - 8FB48ECC1D306C4700BC50A1 /* KeyPath.swift in Sources */, D0DC54771B78150900F79CB0 /* Decodable.swift in Sources */, D0DC54781B78150900F79CB0 /* Operators.swift in Sources */, - 8F3E459C1D31362B00FB71FC /* OptionalKeyPath.swift in Sources */, 8F0062411C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B21C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, - 8F72DC581C3CB8C900A39E10 /* NSValueCastable.swift in Sources */, - 8F3E45A61D327E4500FB71FC /* Decoders.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/Castable.swift b/Sources/Castable.swift deleted file mode 100644 index 976cda6..0000000 --- a/Sources/Castable.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// Castable.swift -// Decodable -// -// Created by Johannes Lund on 2015-09-25. -// Copyright © 2015 anviking. All rights reserved. -// - -import Foundation - -/// Attempt to cast an `Any` to `T` or throw -/// -/// - throws: `DecodingError.typeMismatch(expected, actual, metadata)` -public func cast(_ object: Any) throws -> T { - guard let result = object as? T else { - let metadata = DecodingError.Metadata(object: object) - throw DecodingError.typeMismatch(expected: T.self, actual: type(of: object), metadata) - } - return result -} - -/// Allows overriding default `decode` function from your app. -/// -/// You likely don't want to conform to this yourself. -public protocol DynamicDecodable { - associatedtype DecodedType - - /// A closure describing how this type should be decoded - /// - /// Types also conforming to `Decodable` call this closure - /// from their `decode` function. - /// - /// - note: This is intended as a set-once thing. - static var decoder: (Any) throws -> DecodedType {get set} -} - -extension Decodable where Self: DynamicDecodable, Self.DecodedType == Self { - public static func decode(_ json: Any) throws -> Self { - return try decoder(json) - - } -} - -extension String: Decodable, DynamicDecodable { - public static var decoder: (Any) throws -> String = { try cast($0) } -} -extension Int: Decodable, DynamicDecodable { - public static var decoder: (Any) throws -> Int = { try cast($0) } -} -extension Double: Decodable, DynamicDecodable { - public static var decoder: (Any) throws -> Double = { try cast($0) } -} -extension Bool: Decodable, DynamicDecodable { - public static var decoder: (Any) throws -> Bool = { try cast($0) } -} - -private let iso8601DateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.locale = Locale(identifier: "en_US_POSIX") - formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" - return formatter -}() - -extension Date: Decodable, DynamicDecodable { - /// Default decoder is `Date.decoder(using: iso8601DateFormatter)` - public static var decoder: (Any) throws -> Date = Date.decoder(using: iso8601DateFormatter) - - /// Create a decode closure using a given formatter - /// - /// Example usage: - /// ``` - /// let formatter = DateFormatter(...) - /// Date.decoder = Date.decoder(using: formatter) - /// ``` - public static func decoder(using formatter: DateFormatter) -> (Any) throws -> Date { - return { object in - let string = try String.decode(object) - guard let date = formatter.date(from: string) else { - let metadata = DecodingError.Metadata(object: object) - throw DecodingError.rawRepresentableInitializationError(rawValue: string, metadata) - } - return date - } - } - -} - -extension NSDictionary: Decodable { - public static func decode(_ json: Any) throws -> Self { - return try cast(json) - } -} - -extension NSArray: DynamicDecodable { - public static var decoder: (Any) throws -> NSArray = { try cast($0) } - public static func decode(_ json: Any) throws -> NSArray { - return try decoder(json) - } - -} - - -extension URL: DynamicDecodable, Decodable { - public static var decoder: (Any) throws -> URL = { object in - let string = try String.decode(object) - guard let url = URL(string: string) else { - let metadata = DecodingError.Metadata(object: object) - throw DecodingError.rawRepresentableInitializationError(rawValue: string, metadata) - } - return url - } -} diff --git a/Sources/Decodable.swift b/Sources/Decodable.swift index da638d1..549ddc4 100644 --- a/Sources/Decodable.swift +++ b/Sources/Decodable.swift @@ -8,62 +8,4 @@ import Foundation -public protocol Decodable { - static func decode(_ json: Any) throws -> Self -} - -extension Dictionary where Key: Decodable, Value: Decodable { - public static func decode(_ j: Any) throws -> Dictionary { - return try Dictionary.decoder(key: Key.decode, value: Value.decode)(j) - } -} - -/* FIXME: this causes ambiguity issues, in the meantime resort to `Dictionary.decoder` - https://github.com/Anviking/Decodable/issues/120 - -extension Dictionary where Key: Decodable, Value: Any { - - public static func decode(_ j: Any) throws -> Dictionary { - let valueDecoder: (Any) throws -> Value = { try cast($0) } - return try Dictionary.decoder(key: Key.decode, value: valueDecoder)(j) - } -} -*/ - -extension Array where Element: Decodable { - public static func decode(_ j: Any, ignoreInvalidObjects: Bool = false) throws -> [Element] { - if ignoreInvalidObjects { - return try [Element?].decoder { try? Element.decode($0) }(j).flatMap {$0} - } else { - return try Array.decoder(Element.decode)(j) - } - } -} - - - - -// MARK: Helpers - -/// Attempt to decode one of multiple objects in order until: A: we get a positive match, B: we throw an exception if the last object does not decode -public func decodeAsOneOf(_ json: Any, objectTypes: Decodable.Type...) throws -> Decodable { - for decodable in objectTypes.dropLast() { - if let decoded = try? decodable.decode(json) { - return decoded - } - } - return try objectTypes.last!.decode(json) -} - -/// Attempt to decode one of multiple objects in order until: A: we get a positive match, B: we throw an exception if the last object does not decode -public func decodeArrayAsOneOf(_ json: Any, objectTypes: Decodable.Type...) throws -> [Decodable] { - return try NSArray.decode(json).map { - for decodable in objectTypes.dropLast() { - if let decoded = try? decodable.decode($0) { - return decoded - } - } - return try objectTypes.last!.decode($0) - } -} diff --git a/Sources/Decoders.swift b/Sources/Decoders.swift deleted file mode 100644 index aa646ec..0000000 --- a/Sources/Decoders.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// Closure.swift -// Decodable -// -// Created by Johannes Lund on 2016-07-10. -// Copyright © 2016 anviking. All rights reserved. -// - -import Foundation - -extension Optional { - - /// Creates an optional decoder from a decoder of the Wrapped type - /// - /// This function is used by `=>` and `=>?` overloads when decoding `T?` - /// - /// - parameter wrappedDecoder: A decoder (decode closure) for the wrapped type - /// - returns: A closure takes an JSON object, checks it's `NSNull`, if so returns `nil`, otherwise calls the wrapped decode closure. - static func decoder(_ wrappedDecoder: @escaping (Any) throws -> Wrapped) -> (Any) throws -> Wrapped? { - return { json in - if json is NSNull { - return nil - } else { - return try wrappedDecoder(json) - } - } - } -} - -extension Array { - - /// Creates an array decoder from an element decoder - /// - /// This function is used by `=>` and `=>?` overloads when decoding `[T]` - /// - /// - parameter elementDecoder: A decoder (decode closure) for the `Element` type - /// - throws: if `NSArray.decode` throws or any element decode closure throws - /// - returns: A closure that takes an `NSArray` and maps it using the element decode closure - public static func decoder(_ elementDecoder: @escaping (Any) throws -> Element) -> (Any) throws -> Array { - return { json in - return try NSArray.decode(json).map { try elementDecoder($0) } - } - } -} - -extension Dictionary { - /// Create a dictionary decoder from key- and value- decoders - /// - /// This function is used by `=>` and `=>?` overloads when decoding `[K: V]` - /// - /// - parameter key: A decoder (decode closure) for the `Key` type - /// - parameter value: A decoder (decode closure) for the `Value` type - /// - returns: A closure that takes a `NSDictionary` and "maps" it using key and value decode closures - public static func decoder(key keyDecoder: @escaping (Any) throws -> Key, value valueDecoder: @escaping (Any) throws -> Value) -> (Any) throws -> Dictionary { - return { json in - var dict = Dictionary() - for (key, value) in try NSDictionary.decode(json) { - try dict[keyDecoder(key)] = valueDecoder(value) - } - return dict - } - } -} - diff --git a/Sources/DecodingError.swift b/Sources/DecodingError.swift deleted file mode 100644 index 044e200..0000000 --- a/Sources/DecodingError.swift +++ /dev/null @@ -1,143 +0,0 @@ -// -// DecodingError.swift -// Decodable -// -// Created by Johannes Lund on 2015-07-17. -// Copyright © 2015 anviking. All rights reserved. -// - -import Foundation - -public enum DecodingError: Error, Equatable { - - /// `DecodingError.Metadata` provides information about - /// where an `DecodingError` was thrown in the JSON - /// object graph. - public struct Metadata: Equatable { - - public init(path: [String] = [], object: Any, rootObject: Any? = nil) { - self.path = path - self.object = object - self.rootObject = rootObject - } - - /// The JSON key path to the object that failed to be decoded - public var path: [String] - - /// The JSON object that failed to be decoded - public let object: Any - - /// The root JSON object for which the `path` can be used to find `object` - public var rootObject: Any? - - /// Represents the path to the object that failed decoding with "." as a separator. - public var formattedPath: String { - return path.joined(separator: ".") - } - } - - /// Thrown when optional casting from `Any` fails. - /// - /// This can happen both when trying to access a key on a object - /// that isn't a `NSDictionary`, and failing to cast a `Castable` - /// primitive. - case typeMismatch(expected: Any.Type, actual: Any.Type, Metadata) - - /// Thrown when a given, required, key was not found in a dictionary. - case missingKey(String, Metadata) - - /// Thrown from the `RawRepresentable` extension when - /// `init(rawValue:)` returned `nil`. - case rawRepresentableInitializationError(rawValue: Any, Metadata) - - /// When an error is thrown that isn't `DecodingError`, it - /// will be wrapped in `DecodingError.other` in order to also provide - /// metadata about where the error was thrown. - case other(Error, Metadata) - - public var metadata: Metadata { - get { - switch self { - case .typeMismatch(expected: _, actual: _, let metadata): - return metadata - case .missingKey(_, let metadata): - return metadata - case .rawRepresentableInitializationError(_, let metadata): - return metadata - case .other(_, let metadata): - return metadata - } - } - - set { - switch self { - case let .typeMismatch(expected, actual, _): - self = .typeMismatch(expected: expected, actual: actual, newValue) - case let .missingKey(key, _): - self = .missingKey(key, newValue) - case let .rawRepresentableInitializationError(rawValue, _): - self = DecodingError.rawRepresentableInitializationError(rawValue: rawValue, newValue) - case let .other(error, _): - self = .other(error, newValue) - } - } - - } - - public var debugDescription: String { - switch self { - case let .typeMismatch(expected, actual, metadata): - return "typeMismatch expected: \(expected) but \(metadata.object) is of type \(actual) in \(metadata.formattedPath)" - case let .missingKey(key, metadata): - return "missingKey \(key) in \(metadata.formattedPath) \(metadata.object)" - case let .rawRepresentableInitializationError(rawValue, metadata): - return "rawRepresentableInitializationError: \(rawValue) could not be used to initialize \("TYPE"). (path: \(metadata.formattedPath))" // FIXME - case let .other(error, _): - return "\(error)" - } - } - -} - - -// Allow types to be used in pattern matching -// E.g case typeMismatchError(NSNull.self, _, _) but be careful -// You probably rather want to modify the decode-closure -// There are overloads for this -public func ~=(lhs: T.Type, rhs: Any.Type) -> Bool { - return lhs == rhs -} - -// FIXME: I'm not sure about === equality -public func ==(lhs: DecodingError.Metadata, rhs: DecodingError.Metadata) -> Bool { - return lhs.object as AnyObject === rhs.object as AnyObject - && lhs.path == rhs.path - && lhs.rootObject as AnyObject === rhs.rootObject as AnyObject -} - -public func ==(lhs: DecodingError, rhs: DecodingError) -> Bool { - switch (lhs, rhs) { - case let (.typeMismatch(expected, actual, metadata), .typeMismatch(expected2, actual2, metadata2)): - return expected == expected2 - && actual == actual2 - && metadata == metadata2 - case let (.missingKey(key, metadata), .missingKey(key2, metadata2)): - return key == key2 - && metadata == metadata2 - case let (.rawRepresentableInitializationError(rawValue, metadata), .rawRepresentableInitializationError(rawValue2, metadata2)): - // FIXME: Might be strange - switch (rawValue, rawValue2, metadata == metadata2) { - case let (a as AnyObject, b as AnyObject, true): - return a === b - default: - return false - } - case (.other, .other): - // FIXME: What to do? - print("FIXME: other equality is unimplemented/not supported") - return false - default: - return false - } -} - diff --git a/Sources/KeyPath.swift b/Sources/KeyPath.swift deleted file mode 100644 index 325d425..0000000 --- a/Sources/KeyPath.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// KeyPath.swift -// Decodable -// -// Created by Johannes Lund on 2016-07-09. -// Copyright © 2016 anviking. All rights reserved. -// - -import Foundation - -/// `KeyPath` represents the path to a specific node in a tree of nested dictionaries. -/// -/// Can be created from string and array literals and can be joined by the `=>` operator. -/// ``` -/// let a: KeyPath = "a" -/// let b: KeyPath = ["a", "b"] -/// let c: KeyPath = "a" => "b" => "c" -/// ``` - -public struct KeyPath { - public var keys: [String] - - public init(_ keys: [String]) { - self.keys = keys - } - - public init(_ key: String) { - self.keys = [key] - } - -} - -extension KeyPath: ExpressibleByStringLiteral { - public init(stringLiteral value: String) { - self.keys = [value] - } - - public init(extendedGraphemeClusterLiteral value: String) { - self.keys = [value] - } - - public init(unicodeScalarLiteral value: String) { - self.keys = [value] - } -} - -extension KeyPath: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: String...) { - self.keys = elements - } -} - -extension KeyPath: Equatable { } -public func ==(lhs: KeyPath, rhs: KeyPath) -> Bool { - return lhs.keys == rhs.keys -} diff --git a/Sources/NSValueCastable.swift b/Sources/NSValueCastable.swift deleted file mode 100644 index 695c72d..0000000 --- a/Sources/NSValueCastable.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// NSValueCastable.swift -// Decodable -// -// Created by Johannes Lund on 2016-01-06. -// Copyright © 2016 anviking. All rights reserved. -// - -import Foundation - -extension Int64: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> Int64 { return n.int64Value } -} -extension Int32: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> Int32 { return n.int32Value } -} -extension Int16: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> Int16 { return n.int16Value } -} -extension Int8: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> Int8 { return n.int8Value } -} -extension UInt64: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> UInt64 { return n.uint64Value } -} -extension UInt32: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> UInt32 { return n.uint32Value } -} -extension UInt16: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> UInt16 { return n.uint16Value } -} -extension UInt8: NSNumberCastable { - public static func convertFrom(_ n: NSNumber) -> UInt8 { return n.uint8Value } -} - -/// Provides a default implementation of decode() which casts the object to a NSValue and unsafely casts its value as Self. -public protocol NSValueCastable: Decodable {} - -/// Used to enable decoding to different IntegerTypes from NSNumber. -public protocol NSNumberCastable: NSValueCastable { - static func convertFrom(_ n: NSNumber) -> Self -} - -extension NSValueCastable { - private typealias PointerOfSelf = UnsafeMutablePointer // Why do we have to do this? - public static func decode(_ j: Any) throws -> Self { - let value: NSValue = try cast(j) - let pointer = PointerOfSelf.allocate(capacity: 1) - defer { pointer.deallocate(capacity: 1) } - value.getValue(pointer) - return pointer.move() - } -} - -extension NSNumberCastable { - public static func decode(_ json: Any) throws -> Self { - return try convertFrom(cast(json)) - } -} diff --git a/Sources/Operators.swift b/Sources/Operators.swift index 1e07e2c..976b02c 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -17,37 +17,3 @@ precedencegroup DecodingPrecedence { infix operator => : DecodingPrecedence infix operator =>? : DecodingPrecedence - -public func => (lhs: Any, rhs: KeyPath) throws -> Any { - return try parse(lhs, keyPath: rhs, decoder: { $0 }) -} - - -public func =>? (lhs: Any, rhs: OptionalKeyPath) throws -> Any? { - return try parse(lhs, keyPath: rhs, decoder: Optional.decoder({$0})) -} - -// MARK: - JSONPath - -/// Enables parsing nested objects e.g json => "a" => "b" - -public func => (lhs: KeyPath, rhs: KeyPath) -> KeyPath { - return KeyPath(lhs.keys + rhs.keys) -} - -public func => (lhs: OptionalKeyPath, rhs: OptionalKeyPath) -> OptionalKeyPath { - return OptionalKeyPath(keys: lhs.keys + rhs.markingFirst(required: true).keys) -} - -public func =>? (lhs: OptionalKeyPath, rhs: OptionalKeyPath) -> OptionalKeyPath { - return OptionalKeyPath(keys: lhs.keys + rhs.keys) -} - -public func => (lhs: OptionalKeyPath, rhs: KeyPath) -> OptionalKeyPath { - return OptionalKeyPath(keys: lhs.keys + rhs.keys.map { OptionalKey(key: $0, isRequired: true) }) -} - - -public func =>? (lhs: KeyPath, rhs: OptionalKeyPath) -> OptionalKeyPath { - return OptionalKeyPath(keys: lhs.keys.map { OptionalKey(key: $0, isRequired: true) } + rhs.keys ) -} diff --git a/Sources/OptionalKeyPath.swift b/Sources/OptionalKeyPath.swift deleted file mode 100644 index 4617ff5..0000000 --- a/Sources/OptionalKeyPath.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// OptionalKeyPath.swift -// Decodable -// -// Created by Johannes Lund on 2016-07-09. -// Copyright © 2016 anviking. All rights reserved. -// - -import Foundation - -/// A key in a keyPath that may or may not be required. -/// -/// Trying to access a invalid key in a dictionary with an `OptionalKey` will usually result -/// in a nil return value instead of a thrown error. Unless `isRequired` is `true`, in which -/// it behaves as a "normal" `String` inside a "normal" `KeyPath`. -public struct OptionalKey { - public var key: String - public var isRequired: Bool -} - -extension OptionalKey: CustomStringConvertible { - public var description: String { - return key + (isRequired ? "" : "?") - } -} - -/// `OptionalKeyPath` represents the path to a specific node in a tree of nested dictionaries. -/// -/// Can be created from string and array literals and can be joined by the `=>?` operator. -/// ``` -/// let a: OptionalKeyPath = "a" -/// let b: OptionalKeyPath = ["a", "b"] -/// let c: OptionalKeyPath = "a" =>? "b" =>? "c" -/// ``` -/// Unlike `KeyPath`, `OptionalKeyPath` allows each key to be either required or optional. -///`isRequired` is `false` by default. -/// -/// When a `KeyPath` is converted to a OptionalKeyPath, `isRequired` is set to `true`. -/// ``` -/// let c: OptionalKeyPath = "a" =>? "b" => "c" -/// ^^ -/// isRequired=true -/// ``` -/// In the above example `"c"` is inferred as `KeyPath`, then converted to `OptionalKeyPath` -/// with `isRequired = true` - -public struct OptionalKeyPath { - public var keys: [OptionalKey] - mutating func markFirst(required: Bool) { - if var first = keys.first { - first.isRequired = required - keys[0] = first - } - } - - func markingFirst(required: Bool) -> OptionalKeyPath { - var new = self - if var first = keys.first { - first.isRequired = required - new.keys[0] = first - } - return new - } -} - -extension OptionalKeyPath: ExpressibleByStringLiteral { - public init(stringLiteral value: String) { - self.keys = [OptionalKey(key: value, isRequired: false)] - } - - public init(extendedGraphemeClusterLiteral value: String) { - self.keys = [OptionalKey(key: value, isRequired: false)] - } - - public init(unicodeScalarLiteral value: String) { - self.keys = [OptionalKey(key: value, isRequired: false)] - } -} - -extension OptionalKeyPath: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: String...) { - self.keys = elements.map { OptionalKey(key: $0, isRequired: false) } - } -} - -// MARK: Equality - -extension OptionalKey: Equatable {} -public func == (lhs: OptionalKey, rhs: OptionalKey) -> Bool { - return lhs.key == rhs.key && lhs.isRequired == rhs.isRequired -} diff --git a/Sources/Parse.swift b/Sources/Parse.swift deleted file mode 100644 index ee5520a..0000000 --- a/Sources/Parse.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// Parse.swift -// Decodable -// -// Created by Johannes Lund on 2015-08-13. -// Copyright © 2015 anviking. All rights reserved. -// - -import Foundation - -func parse(_ json: Any, _ keyPath: KeyPath) throws -> Any { - var currentDict = json - - for (index, key) in keyPath.keys.enumerated() { - guard let result = try NSDictionary.decode(currentDict)[key] else { - let currentPath = keyPath.keys[0 ..< index] - let metadata = DecodingError.Metadata(path: Array(currentPath), object: currentDict, rootObject: json) - throw DecodingError.missingKey(key, metadata) - } - - currentDict = result - } - - return currentDict -} - -func parse(_ json: Any, _ path: OptionalKeyPath) throws -> Any? { - var currentDict = json - - for (index, key) in path.keys.enumerated() { - guard let result = try NSDictionary.decode(currentDict)[key.key] else { - if key.isRequired { - let currentPath = path.keys[0 ..< index].map { $0.key } - let metadata = DecodingError.Metadata(path: currentPath, object: currentDict, rootObject: json) - throw DecodingError.missingKey(key.key, metadata) - } else { - return nil - } - } - currentDict = result - } - - return currentDict -} -public func parse(_ json: Any, keyPath: KeyPath, decoder: ((Any) throws -> T)) throws -> T { - let object = try parse(json, keyPath) - return try catchAndRethrow(json, keyPath) { try decoder(object) } -} - -// FIXME: Should perhaps not return T?, but this way we don't have to flatMap in certain overloads -public func parse(_ json: Any, keyPath: OptionalKeyPath, decoder: ((Any) throws -> T?)) throws -> T? { - guard let object = try parse(json, keyPath) else { return nil } - return try catchAndRethrow(json, keyPath) { try decoder(object) } -} - - -// MARK: - Helpers - -func catchMissingKeyAndReturnNil(_ closure: () throws -> T) throws -> T? { - do { - return try closure() - } catch DecodingError.missingKey { - return nil - } -} - -func catchAndRethrow(_ json: Any, _ keyPath: KeyPath, block: () throws -> T) throws -> T { - do { - return try block() - } catch let error as DecodingError { - var error = error - error.metadata.path = keyPath.keys + error.metadata.path - error.metadata.rootObject = json - throw error - } catch let error { - throw error - } -} - -func catchAndRethrow(_ json: Any, _ keyPath: OptionalKeyPath, block: () throws -> T) throws -> T { - do { - return try block() - } catch let error as DecodingError { - var error = error - error.metadata.path = keyPath.keys.map{$0.key} + error.metadata.path - error.metadata.rootObject = json - throw error - } catch let error { - throw error - } -} diff --git a/Sources/Playground.playground/Contents.swift b/Sources/Playground.playground/Contents.swift deleted file mode 100644 index 58eb11b..0000000 --- a/Sources/Playground.playground/Contents.swift +++ /dev/null @@ -1,4 +0,0 @@ -//: Playground - noun: a place where people can play - - - diff --git a/Sources/Playground.playground/contents.xcplayground b/Sources/Playground.playground/contents.xcplayground deleted file mode 100644 index 5da2641..0000000 --- a/Sources/Playground.playground/contents.xcplayground +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Sources/RawRepresentableDecodable.swift b/Sources/RawRepresentableDecodable.swift index d8ae331..1d542cd 100644 --- a/Sources/RawRepresentableDecodable.swift +++ b/Sources/RawRepresentableDecodable.swift @@ -12,14 +12,15 @@ * I could not find a way to implicitly declare RawRepresentable conforming to Decodable, what would make all enums Decodable automatically. * Because of that for an enum to be compatible with Decodable operators it must be declared as implementing Decodable protocol. */ -public extension RawRepresentable where RawValue: Decodable, Self: Decodable { - - static func decode(_ json: Any) throws -> Self { - let rawValue = try RawValue.decode(json) - guard let rawRepresentable = Self(rawValue: rawValue) else { - let metadata = DecodingError.Metadata(object: json) - throw DecodingError.rawRepresentableInitializationError(rawValue: rawValue, metadata) - } - return rawRepresentable - } -} +//public extension RawRepresentable where RawValue: Decodable, Self: Decodable { +// +// static func decode(_ json: Any) throws -> Self { +// let rawValue = try RawValue.decode(json) +// guard let rawRepresentable = Self(rawValue: rawValue) else { +// let metadata = DecodingError.Metadata(object: json) +// throw DecodingError.rawRepresentableInitializationError(rawValue: rawValue, metadata) +// } +// return rawRepresentable +// } +//} + From 710593e95d4de5507db55ab4e709f65016af7da3 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Sun, 29 Oct 2017 03:30:23 +0100 Subject: [PATCH 2/4] remove code generation --- Decodable.xcodeproj/project.pbxproj | 86 -------- Generator/Generator.swift | 251 ------------------------ Generator/Templates/Documentation.swift | 7 - Generator/Templates/Header.swift | 10 - 4 files changed, 354 deletions(-) delete mode 100755 Generator/Generator.swift delete mode 100644 Generator/Templates/Documentation.swift delete mode 100644 Generator/Templates/Header.swift diff --git a/Decodable.xcodeproj/project.pbxproj b/Decodable.xcodeproj/project.pbxproj index 073d91e..3099fe0 100644 --- a/Decodable.xcodeproj/project.pbxproj +++ b/Decodable.xcodeproj/project.pbxproj @@ -24,7 +24,6 @@ 8F0062421C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; 8F3E459F1D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F3E45A01D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; - 8F3E45B81D32884700FB71FC /* Documentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45AE1D32853F00FB71FC /* Documentation.swift */; }; 8F4453EF1D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; 8F4453F01D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; 8F4B52651B5BAA5700FDCBA7 /* ArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */; }; @@ -40,7 +39,6 @@ 8F87BCBB1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; }; 8F87BCBC1B580CE200E53A8C /* ErrorPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F87BCBA1B580CE200E53A8C /* ErrorPathTests.swift */; }; 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; - 8FA733591D328D13003A90A7 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E45AF1D32853F00FB71FC /* Header.swift */; }; 8FD3D92F1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FD3D92E1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift */; }; 8FD3D9301C270A2D00D1AF4E /* MissingKeyOperatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FD3D92E1C270A2D00D1AF4E /* MissingKeyOperatorTests.swift */; }; 8FE7B5661B4C9FB900837609 /* Decodable.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FE7B5651B4C9FB900837609 /* Decodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -96,10 +94,7 @@ 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodableTests.swift; sourceTree = ""; }; 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodable.swift; sourceTree = ""; }; 8F00623E1C81EF61007BCF48 /* Overloads.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Overloads.swift; sourceTree = ""; }; - 8F0062481C81F4A2007BCF48 /* Generator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Generator.swift; sourceTree = ""; }; 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPathTests.swift; sourceTree = ""; }; - 8F3E45AE1D32853F00FB71FC /* Documentation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Documentation.swift; sourceTree = ""; }; - 8F3E45AF1D32853F00FB71FC /* Header.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; 8F4453EE1D369FF200C19099 /* ParseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseTests.swift; sourceTree = ""; }; 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = ""; }; 8F53521C1BE4112900E3563A /* DictionaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DictionaryTests.swift; sourceTree = ""; }; @@ -177,30 +172,10 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 8F0062471C81F4A2007BCF48 /* Code Generation */ = { - isa = PBXGroup; - children = ( - 8F0062481C81F4A2007BCF48 /* Generator.swift */, - 8F3E45AD1D32853F00FB71FC /* Templates */, - ); - name = "Code Generation"; - path = Generator; - sourceTree = ""; - }; - 8F3E45AD1D32853F00FB71FC /* Templates */ = { - isa = PBXGroup; - children = ( - 8F3E45AE1D32853F00FB71FC /* Documentation.swift */, - 8F3E45AF1D32853F00FB71FC /* Header.swift */, - ); - path = Templates; - sourceTree = ""; - }; 8FE7B5581B4C9FB900837609 = { isa = PBXGroup; children = ( 8FE7B5641B4C9FB900837609 /* Decodable */, - 8F0062471C81F4A2007BCF48 /* Code Generation */, 8FE7B5701B4C9FB900837609 /* DecodableTests */, 8FE7B5631B4C9FB900837609 /* Products */, ); @@ -310,7 +285,6 @@ isa = PBXNativeTarget; buildConfigurationList = 17FB81081B530FED0012F106 /* Build configuration list for PBXNativeTarget "Decodable-Mac" */; buildPhases = ( - 8F0062451C81F348007BCF48 /* ShellScript */, 17FB80F21B530FED0012F106 /* Sources */, 17FB80F31B530FED0012F106 /* Frameworks */, 17FB80F41B530FED0012F106 /* Headers */, @@ -347,7 +321,6 @@ isa = PBXNativeTarget; buildConfigurationList = 57FCDE621BA283C900130C48 /* Build configuration list for PBXNativeTarget "Decodable-tvOS" */; buildPhases = ( - 8F00624B1C81F6F1007BCF48 /* ShellScript */, 57FCDE5A1BA283C900130C48 /* Sources */, 57FCDE5F1BA283C900130C48 /* Frameworks */, 57FCDE601BA283C900130C48 /* Headers */, @@ -366,7 +339,6 @@ isa = PBXNativeTarget; buildConfigurationList = 8FE7B5761B4C9FB900837609 /* Build configuration list for PBXNativeTarget "Decodable-iOS" */; buildPhases = ( - 8F0062441C81F26B007BCF48 /* ShellScript */, 8FE7B55D1B4C9FB900837609 /* Sources */, 8FE7B55E1B4C9FB900837609 /* Frameworks */, 8FE7B55F1B4C9FB900837609 /* Headers */, @@ -403,7 +375,6 @@ isa = PBXNativeTarget; buildConfigurationList = D0DC54761B7814D200F79CB0 /* Build configuration list for PBXNativeTarget "Decodable-watchOS" */; buildPhases = ( - 8F0062461C81F350007BCF48 /* ShellScript */, D0DC546A1B7814D200F79CB0 /* Sources */, D0DC546B1B7814D200F79CB0 /* Frameworks */, D0DC546C1B7814D200F79CB0 /* Headers */, @@ -525,61 +496,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 8F0062441C81F26B007BCF48 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ -z \"$CI\" ]; then\n cd \"${SRCROOT}/Generator\"\n ./Generator.swift\nfi"; - }; - 8F0062451C81F348007BCF48 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ -z \"$CI\" ]; then\n cd \"${SRCROOT}/Generator\"\n ./Generator.swift\nfi"; - }; - 8F0062461C81F350007BCF48 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ -z \"$CI\" ]; then\n cd \"${SRCROOT}/Generator\"\n ./Generator.swift\nfi"; - }; - 8F00624B1C81F6F1007BCF48 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ -z \"$CI\" ]; then\n cd \"${SRCROOT}/Generator\"\n ./Generator.swift\nfi"; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 17FB80F21B530FED0012F106 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -630,10 +546,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8FA733591D328D13003A90A7 /* Header.swift in Sources */, 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */, 8F00623F1C81EF61007BCF48 /* Overloads.swift in Sources */, - 8F3E45B81D32884700FB71FC /* Documentation.swift in Sources */, 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */, 65DB18B01C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); diff --git a/Generator/Generator.swift b/Generator/Generator.swift deleted file mode 100755 index 2b2e051..0000000 --- a/Generator/Generator.swift +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/xcrun --sdk macosx swift - -// -// Generator.swift -// Decodable -// -// Created by Johannes Lund on 2016-02-27. -// Copyright © 2016 anviking. All rights reserved. -// - -// For generating overloads - -import Foundation - -// ---------------------------------------------------------------------------------------- -// MARK: Documentation -// ---------------------------------------------------------------------------------------- - -struct Behaviour { - let throwsIfKeyMissing: Bool - let throwsIfNull: Bool - let throwsFromDecodeClosure: Bool -} - - -let fileManager = FileManager.default -let documentationTemplate = try String(contentsOfFile: fileManager.currentDirectoryPath + "/Templates/Documentation.swift") - -func documentationFromTemplate(path: String, throwsIf: String, returns: String) -> String { - return documentationTemplate - .replacingOccurrences(of: "{path}", with: path) - .replacingOccurrences(of: "{throws}", with: throwsIf) - .replacingOccurrences(of: "{returns}", with: returns) -} - -func generateDocumentationComment(_ behaviour: Behaviour) -> String { - switch (behaviour.throwsIfKeyMissing, behaviour.throwsIfNull) { - case (true, true): - return documentationFromTemplate( - path: "`KeyPath`– can be appended using with `=>` or `=>?`", - throwsIf: "`DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys", - returns: "something" - ) - case (true, false): - return documentationFromTemplate( - path: "`KeyPath`– can be appended using with `=>` or `=>?`", - throwsIf: "`DecodingError` if a key is missing or decoding fails.", - returns: "`nil` if the object at `path` is `NSNull`" - ) - case (false, false): - return documentationFromTemplate( - path: "`KeyPath`– can be appended using with `=>` or `=>?`", - throwsIf: "`DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys", - returns: "`nil` if the object at `path` is `NSNull` or if any optional key is missing." - ) - case (false, true): - fatalError("This case should never happen, right?") - } -} - -// ---------------------------------------------------------------------------------------- -// MARK: -// ---------------------------------------------------------------------------------------- - - -class TypeNameProvider { - var names = Array(["A", "B", "C", "D", "E", "F", "G"].reversed()) - var takenNames: [Unique: String] = [:] - subscript(key: Unique) -> String { - if let name = takenNames[key] { - return name - } - - let n = names.popLast()! - takenNames[key] = n - return n - } - -} - -struct Unique: Hashable, Equatable { - static var counter = 0 - let value: Int - init() { - Unique.counter += 1 - value = Unique.counter - } - var hashValue: Int { - return value.hashValue - } -} - -func == (a: Unique, b: Unique) -> Bool { - return a.value == b.value -} - -indirect enum Decodable { - case T(Unique) - // case AnyObject - case Array(Decodable) - case Optional(Decodable) - case Dictionary(Decodable, Decodable) - - func decodeClosure(_ provider: TypeNameProvider) -> String { - switch self { - case .T(let key): - return "\(provider[key]).decode" - // case .AnyObject: - // return "{$0}" - case .Optional(let T): - return "Optional.decoder(\(T.decodeClosure(provider)))" - case .Array(let T): - return "Array.decoder(\(T.decodeClosure(provider)))" - case .Dictionary(let K, let T): - return "Dictionary.decoder(key: \(K.decodeClosure(provider)), value: \(T.decodeClosure(provider)))" - } - } - - func typeString(_ provider: TypeNameProvider) -> String { - switch self { - case .T(let unique): - return provider[unique] - case .Optional(let T): - return "\(T.typeString(provider))?" - case .Array(let T): - return "[\(T.typeString(provider))]" - case .Dictionary(let K, let T): - return "[\(K.typeString(provider)): \(T.typeString(provider))]" - } - } - - func generateAllPossibleChildren(_ deepness: Int) -> [Decodable] { - guard deepness > 0 else { return [.T(Unique())] } - - var array = [Decodable]() - array += generateAllPossibleChildren(deepness - 1).flatMap(filterChainedOptionals) - array += generateAllPossibleChildren(deepness - 1).map { .Array($0) } - array += generateAllPossibleChildren(deepness - 1).map { .Dictionary(.T(Unique()),$0) } - array += [.T(Unique())] - return array - } - - func wrapInOptionalIfNeeded() -> Decodable { - switch self { - case .Optional: - return self - default: - return .Optional(self) - } - } - - var isOptional: Bool { - switch self { - case .Optional: - return true - default: - return false - } - } - - func generateOverloads(_ operatorString: String) -> [String] { - let provider = TypeNameProvider() - let behaviour: Behaviour - let keyPathType: String - - let returnType = typeString(provider) - let overloads = [String]() - - let arguments = provider.takenNames.values.sorted().map { $0 + ": Decodable" } - let generics = arguments.count > 0 ? "<\(arguments.joined(separator: ", "))>" : "" - - switch operatorString { - case "=>": - behaviour = Behaviour(throwsIfKeyMissing: true, throwsIfNull: !isOptional, throwsFromDecodeClosure: true) - keyPathType = "KeyPath" - - /* - // Start again - guard isOptional else { break } - let otherBehaviour = Behaviour(throwsIfKeyMissing: false, throwsIfNull: !isOptional, throwsFromDecodeClosure: true) - let documentation = generateDocumentationComment(otherBehaviour) - overloads.append(documentation + "public func \(operatorString) \(generics)(json: AnyObject, keyPath: OptionalKeyPath) throws -> \(returnType) {\n" + - " return try parse(json, keyPath: keyPath.markingFirst(required: true), decode: \(decodeClosure(provider)))\n" + - "}" - ) - */ - - case "=>?": - //returnType += "?" - // Never trows if null - behaviour = Behaviour(throwsIfKeyMissing: false, throwsIfNull: false, throwsFromDecodeClosure: true) - keyPathType = "OptionalKeyPath" - default: - fatalError() - } - - let documentation = generateDocumentationComment(behaviour) - return overloads + [documentation + "public func \(operatorString) \(generics)(json: Any, keyPath: \(keyPathType)) throws -> \(returnType) {\n" + - " return try parse(json, keyPath: keyPath, decoder: \(decodeClosure(provider)))\n" + - "}" - ] - } -} - -func filterChainedOptionals(type: Decodable) -> Decodable? { - switch type { - case .Optional: - return nil - default: - return .Optional(type) - } -} - -func filterOptionals(type: Decodable) -> Decodable? { - switch type { - case .Optional: - return nil - default: - return type - } -} - - -let file = "Overloads.swift" -let sourcesDirectory = fileManager.currentDirectoryPath + "/../Sources" - - -let filename = "Overloads.swift" -let path = sourcesDirectory + "/" + filename - -var dateFormatter = DateFormatter() -dateFormatter.dateStyle = .short - -let date = dateFormatter.string(from: Date()) - -let overloads = Decodable.T(Unique()).generateAllPossibleChildren(4) -let types = overloads.map { $0.typeString(TypeNameProvider()) } -let all = overloads.flatMap { $0.generateOverloads("=>") } + overloads.flatMap(filterOptionals).map{ $0.wrapInOptionalIfNeeded() }.flatMap { $0.generateOverloads("=>?") } - -do { - var template = try String(contentsOfFile: fileManager.currentDirectoryPath + "/Templates/Header.swift") - template = template.replacingOccurrences(of: "{filename}", with: filename) - template = template.replacingOccurrences(of: "{by}", with: "Generator.swift") - template = template.replacingOccurrences(of: "{overloads}", with: types.joined(separator: ", ")) - template = template.replacingOccurrences(of: "{count}", with: "\(all.count)") - let text = (template as String) + "\n" + all.joined(separator: "\n\n") - try text.write(toFile: sourcesDirectory + "/Overloads.swift", atomically: false, encoding: String.Encoding.utf8) -} -catch { - print(error) -} diff --git a/Generator/Templates/Documentation.swift b/Generator/Templates/Documentation.swift deleted file mode 100644 index 69166ba..0000000 --- a/Generator/Templates/Documentation.swift +++ /dev/null @@ -1,7 +0,0 @@ -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: {path} -/// - throws: {throws} -/// - returns: {returns} -/// diff --git a/Generator/Templates/Header.swift b/Generator/Templates/Header.swift deleted file mode 100644 index f46df2a..0000000 --- a/Generator/Templates/Header.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// {filename} -// Decodable -// -// Generated automatically by {by} as a build phase. -// Copyright © 2016 anviking. All rights reserved. -// - -// {count} overloads were generated with the following return types: -// {overloads} From dbb7838c5c78754a8b9d648fe117a37bc14c8350 Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Sun, 29 Oct 2017 03:32:59 +0100 Subject: [PATCH 3/4] add new overloads --- Decodable.xcodeproj/project.pbxproj | 10 - Sources/Operators.swift | 33 + Sources/Overloads.swift | 1803 --------------------------- 3 files changed, 33 insertions(+), 1813 deletions(-) delete mode 100644 Sources/Overloads.swift diff --git a/Decodable.xcodeproj/project.pbxproj b/Decodable.xcodeproj/project.pbxproj index 3099fe0..ba0c171 100644 --- a/Decodable.xcodeproj/project.pbxproj +++ b/Decodable.xcodeproj/project.pbxproj @@ -18,10 +18,6 @@ 65DB18B11C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; 65DB18B21C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; 65DB18B31C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; - 8F00623F1C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; - 8F0062401C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; - 8F0062411C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; - 8F0062421C81EF61007BCF48 /* Overloads.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F00623E1C81EF61007BCF48 /* Overloads.swift */; }; 8F3E459F1D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F3E45A01D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F4453EF1D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; @@ -93,7 +89,6 @@ 57FCDE651BA283C900130C48 /* Decodable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Decodable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodableTests.swift; sourceTree = ""; }; 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodable.swift; sourceTree = ""; }; - 8F00623E1C81EF61007BCF48 /* Overloads.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Overloads.swift; sourceTree = ""; }; 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPathTests.swift; sourceTree = ""; }; 8F4453EE1D369FF200C19099 /* ParseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseTests.swift; sourceTree = ""; }; 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = ""; }; @@ -200,7 +195,6 @@ 8FE7B5651B4C9FB900837609 /* Decodable.h */, 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */, 8F956D1E1B4D6FF700243072 /* Operators.swift */, - 8F00623E1C81EF61007BCF48 /* Overloads.swift */, 8FE7B57C1B4CA01400837609 /* Decodable.swift */, 8FE7B5671B4C9FB900837609 /* Info.plist */, ); @@ -503,7 +497,6 @@ files = ( 17FB810E1B5311840012F106 /* Decodable.swift in Sources */, 17FB810F1B5311870012F106 /* Operators.swift in Sources */, - 8F0062401C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B11C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -537,7 +530,6 @@ files = ( 57FCDE5D1BA283C900130C48 /* Decodable.swift in Sources */, 57FCDE5E1BA283C900130C48 /* Operators.swift in Sources */, - 8F0062421C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B31C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -547,7 +539,6 @@ buildActionMask = 2147483647; files = ( 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */, - 8F00623F1C81EF61007BCF48 /* Overloads.swift in Sources */, 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */, 65DB18B01C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); @@ -582,7 +573,6 @@ files = ( D0DC54771B78150900F79CB0 /* Decodable.swift in Sources */, D0DC54781B78150900F79CB0 /* Operators.swift in Sources */, - 8F0062411C81EF61007BCF48 /* Overloads.swift in Sources */, 65DB18B21C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/Operators.swift b/Sources/Operators.swift index 976b02c..e842255 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -17,3 +17,36 @@ precedencegroup DecodingPrecedence { infix operator => : DecodingPrecedence infix operator =>? : DecodingPrecedence + +// Dict -> T +func => (container: KeyedDecodingContainer, key: Key) throws -> A { + return try container.decode(A.self, forKey: key) +} + +// Dict -> Dict +func => (container: KeyedDecodingContainer, key: Key) throws -> KeyedDecodingContainer { + return try container.nestedContainer(keyedBy: Key.self, forKey: key) +} + +// Dict -> Dict? +func => (container: KeyedDecodingContainer, key: Key) throws -> KeyedDecodingContainer? { + if container.contains(key) { + return try container.nestedContainer(keyedBy: Key.self, forKey: key) + } else { + return nil + } +} + +// Dict? -> Dict? +func =>? (container: KeyedDecodingContainer?, key: Key) throws -> KeyedDecodingContainer? { + if let container = container, container.contains(key) { + return try container.nestedContainer(keyedBy: Key.self, forKey: key) + } else { + return nil + } +} + +// Dict? -> Dict +func => (container: KeyedDecodingContainer?, key: Key) throws -> KeyedDecodingContainer? { + return try container?.nestedContainer(keyedBy: Key.self, forKey: key) +} diff --git a/Sources/Overloads.swift b/Sources/Overloads.swift deleted file mode 100644 index a524eeb..0000000 --- a/Sources/Overloads.swift +++ /dev/null @@ -1,1803 +0,0 @@ -// -// Overloads.swift -// Decodable -// -// Generated automatically by Generator.swift as a build phase. -// Copyright © 2016 anviking. All rights reserved. -// - -// 163 overloads were generated with the following return types: -// [[A]?]?, [[A: B]?]?, [A?]?, [[A?]]?, [[[A]]]?, [[[A: B]]]?, [[A]]?, [[A: B?]]?, [[A: [B]]]?, [[A: [B: C]]]?, [[A: B]]?, [A]?, [A: [B]?]?, [A: [B: C]?]?, [A: B?]?, [A: [B?]]?, [A: [[B]]]?, [A: [[B: C]]]?, [A: [B]]?, [A: [B: C?]]?, [A: [B: [C]]]?, [A: [B: [C: D]]]?, [A: [B: C]]?, [A: B]?, A?, [[A?]?], [[[A]]?], [[[A: B]]?], [[A]?], [[A: B?]?], [[A: [B]]?], [[A: [B: C]]?], [[A: B]?], [A?], [[[A]?]], [[[A: B]?]], [[A?]], [[[A?]]], [[[[A]]]], [[[[A: B]]]], [[[A]]], [[[A: B?]]], [[[A: [B]]]], [[[A: [B: C]]]], [[[A: B]]], [[A]], [[A: [B]?]], [[A: [B: C]?]], [[A: B?]], [[A: [B?]]], [[A: [[B]]]], [[A: [[B: C]]]], [[A: [B]]], [[A: [B: C?]]], [[A: [B: [C]]]], [[A: [B: [C: D]]]], [[A: [B: C]]], [[A: B]], [A], [A: [B?]?], [A: [[B]]?], [A: [[B: C]]?], [A: [B]?], [A: [B: C?]?], [A: [B: [C]]?], [A: [B: [C: D]]?], [A: [B: C]?], [A: B?], [A: [[B]?]], [A: [[B: C]?]], [A: [B?]], [A: [[B?]]], [A: [[[B]]]], [A: [[[B: C]]]], [A: [[B]]], [A: [[B: C?]]], [A: [[B: [C]]]], [A: [[B: [C: D]]]], [A: [[B: C]]], [A: [B]], [A: [B: [C]?]], [A: [B: [C: D]?]], [A: [B: C?]], [A: [B: [C?]]], [A: [B: [[C]]]], [A: [B: [[C: D]]]], [A: [B: [C]]], [A: [B: [C: D?]]], [A: [B: [C: [D]]]], [A: [B: [C: [D: E]]]], [A: [B: [C: D]]], [A: [B: C]], [A: B], A - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Optional.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(A.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: B?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: D]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: B]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError` if a key is missing or decoding fails. -/// - returns: `nil` if the object at `path` is `NSNull` -/// -public func => (json: Any, keyPath: KeyPath) throws -> A? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(A.decode)) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A?]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Array.decoder(Optional.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A]]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Array.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: B]]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Array.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B?]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B]]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: C]]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B]?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A?] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Optional.decoder(A.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A]?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Optional.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: B]?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Optional.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A?]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Array.decoder(Optional.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[[A]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Array.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[[A: B]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Array.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: B?]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: [B]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: [B: C]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[[A: B]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Array.decoder(A.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B]?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: C]?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B?]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B?]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [[B]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [[B: C]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: C?]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: [C]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: [C: D]]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: [B: C]]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [[A: B]] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A] { - return try parse(json, keyPath: keyPath, decoder: Array.decoder(A.decode)) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B?]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B]]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: C]]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C?]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C]]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: D]]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C]?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: B?] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B]?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: C]?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B?]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[[B]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[[B: C]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: C?]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: [C]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: [C: D]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [[B: C]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C]?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: D]?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C?]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C?]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [[C]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [[C: D]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: D?]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Optional.decoder(D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: [D]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Array.decoder(D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: [D: E]]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Dictionary.decoder(key: D.decode, value: E.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: [C: D]]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: [B: C]] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> [A: B] { - return try parse(json, keyPath: keyPath, decoder: Dictionary.decoder(key: A.decode, value: B.decode)) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatchError`,`.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: something -/// -public func => (json: Any, keyPath: KeyPath) throws -> A { - return try parse(json, keyPath: keyPath, decoder: A.decode) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A?]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Array.decoder(Optional.decoder(A.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Array.decoder(Array.decoder(A.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: B]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: B?]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: C]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: B]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Optional.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Optional.decoder(Array.decoder(A.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: B]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Optional.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Array.decoder(Optional.decoder(A.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[[A]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Array.decoder(Array.decoder(A.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[[A: B]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Array.decoder(A.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: B?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: [B]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: [B: C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[[A: B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Array.decoder(A.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: C]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: B?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [[B]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [[B: C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: C?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: [C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: [C: D]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: [B: C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [[A: B]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(Dictionary.decoder(key: A.decode, value: B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Array.decoder(A.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B?]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Optional.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: C]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: C?]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: D]]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: C]?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: B?]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Optional.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: C]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Optional.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Optional.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[[B]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Array.decoder(B.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[[B: C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Array.decoder(B.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: C?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: [C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: [C: D]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [[B: C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(Dictionary.decoder(key: B.decode, value: C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Array.decoder(B.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(Array.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: D]?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(Dictionary.decoder(key: C.decode, value: D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: C?]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Optional.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Optional.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [[C]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Array.decoder(C.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [[C: D]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(Dictionary.decoder(key: C.decode, value: D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Array.decoder(C.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: D?]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Optional.decoder(D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: [D]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Array.decoder(D.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: [D: E]]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: Dictionary.decoder(key: D.decode, value: E.decode)))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: [C: D]]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: Dictionary.decoder(key: C.decode, value: D.decode))))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: [B: C]]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: Dictionary.decoder(key: B.decode, value: C.decode)))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> [A: B]? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(Dictionary.decoder(key: A.decode, value: B.decode))) -} - -/// Retrieves the object at `path` from `json` and decodes it according to the return type -/// -/// - parameter json: An object from NSJSONSerialization, preferably a `NSDictionary`. -/// - parameter path: `KeyPath`– can be appended using with `=>` or `=>?` -/// - throws: `DecodingError.typeMismatch, `.other(error, metadata)` or possible `.missingKeyError` on required keys -/// - returns: `nil` if the object at `path` is `NSNull` or if any optional key is missing. -/// -public func =>? (json: Any, keyPath: OptionalKeyPath) throws -> A? { - return try parse(json, keyPath: keyPath, decoder: Optional.decoder(A.decode)) -} \ No newline at end of file From fedd3a1292226ea04263e42f2eb17d2628adb55b Mon Sep 17 00:00:00 2001 From: Johannes Lund Date: Sun, 29 Oct 2017 11:24:47 +0100 Subject: [PATCH 4/4] Lets try this --- Decodable.xcodeproj/project.pbxproj | 20 +++++------ Sources/Decodable.swift | 11 ------ Sources/Operators.swift | 56 +++++++++++++++++++++-------- Sources/UnsafeKey.swift | 30 ++++++++++++++++ 4 files changed, 82 insertions(+), 35 deletions(-) delete mode 100644 Sources/Decodable.swift create mode 100644 Sources/UnsafeKey.swift diff --git a/Decodable.xcodeproj/project.pbxproj b/Decodable.xcodeproj/project.pbxproj index ba0c171..ff8f401 100644 --- a/Decodable.xcodeproj/project.pbxproj +++ b/Decodable.xcodeproj/project.pbxproj @@ -8,9 +8,7 @@ /* Begin PBXBuildFile section */ 17FB81011B530FED0012F106 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17FB80F71B530FED0012F106 /* Decodable.framework */; }; - 17FB810E1B5311840012F106 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; 17FB810F1B5311870012F106 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; - 57FCDE5D1BA283C900130C48 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; 57FCDE5E1BA283C900130C48 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; 651A8C971C29AC5F00DE4D53 /* RawRepresentableDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */; }; 651A8C981C29AC5F00DE4D53 /* RawRepresentableDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */; }; @@ -18,6 +16,10 @@ 65DB18B11C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; 65DB18B21C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; 65DB18B31C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */; }; + 8F27FAE51FA5757F00674C8B /* UnsafeKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */; }; + 8F27FAE61FA5757F00674C8B /* UnsafeKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */; }; + 8F27FAE71FA5757F00674C8B /* UnsafeKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */; }; + 8F27FAE81FA5757F00674C8B /* UnsafeKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */; }; 8F3E459F1D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F3E45A01D313A7000FB71FC /* KeyPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */; }; 8F4453EF1D369FF200C19099 /* ParseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4453EE1D369FF200C19099 /* ParseTests.swift */; }; @@ -40,14 +42,12 @@ 8FE7B5661B4C9FB900837609 /* Decodable.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FE7B5651B4C9FB900837609 /* Decodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8FE7B56D1B4C9FB900837609 /* Decodable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8FE7B5621B4C9FB900837609 /* Decodable.framework */; }; 8FE7B5721B4C9FB900837609 /* DecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */; }; - 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; 9E2DA75C1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */; }; 9E2DA75D1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */; }; 9E2DA75F1CBC784700CAF3DF /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75E1CBC784700CAF3DF /* Vehicle.swift */; }; 9E2DA7601CBC784700CAF3DF /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DA75E1CBC784700CAF3DF /* Vehicle.swift */; }; 9E2DA7651CBC802200CAF3DF /* Vehicle.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E2DA7641CBC802200CAF3DF /* Vehicle.json */; }; 9E2DA7661CBC802200CAF3DF /* Vehicle.json in Resources */ = {isa = PBXBuildFile; fileRef = 9E2DA7641CBC802200CAF3DF /* Vehicle.json */; }; - D0DC54771B78150900F79CB0 /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B57C1B4CA01400837609 /* Decodable.swift */; }; D0DC54781B78150900F79CB0 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F956D1E1B4D6FF700243072 /* Operators.swift */; }; FF0060981B5453C600D8CB77 /* DecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */; }; FF00609E1B5454F400D8CB77 /* DecodableExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF00609D1B5454F400D8CB77 /* DecodableExtensionTests.swift */; }; @@ -89,6 +89,7 @@ 57FCDE651BA283C900130C48 /* Decodable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Decodable.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 651A8C961C29AC5E00DE4D53 /* RawRepresentableDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodableTests.swift; sourceTree = ""; }; 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawRepresentableDecodable.swift; sourceTree = ""; }; + 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsafeKey.swift; sourceTree = ""; }; 8F3E459E1D313A7000FB71FC /* KeyPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPathTests.swift; sourceTree = ""; }; 8F4453EE1D369FF200C19099 /* ParseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseTests.swift; sourceTree = ""; }; 8F4B52641B5BAA5700FDCBA7 /* ArrayTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = ""; }; @@ -105,7 +106,6 @@ 8FE7B56C1B4C9FB900837609 /* DecodableTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "DecodableTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 8FE7B5711B4C9FB900837609 /* DecodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodableTests.swift; sourceTree = ""; }; 8FE7B5731B4C9FB900837609 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 8FE7B57C1B4CA01400837609 /* Decodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decodable.swift; sourceTree = ""; }; 9E2DA75B1CBC77AB00CAF3DF /* DecodeAsOneOfTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecodeAsOneOfTests.swift; sourceTree = ""; }; 9E2DA75E1CBC784700CAF3DF /* Vehicle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = ""; }; 9E2DA7641CBC802200CAF3DF /* Vehicle.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Vehicle.json; path = JSONExamples/Vehicle.json; sourceTree = ""; }; @@ -195,7 +195,7 @@ 8FE7B5651B4C9FB900837609 /* Decodable.h */, 65DB18AF1C29AC0E003BDA5C /* RawRepresentableDecodable.swift */, 8F956D1E1B4D6FF700243072 /* Operators.swift */, - 8FE7B57C1B4CA01400837609 /* Decodable.swift */, + 8F27FAE41FA5757F00674C8B /* UnsafeKey.swift */, 8FE7B5671B4C9FB900837609 /* Info.plist */, ); name = Decodable; @@ -495,7 +495,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 17FB810E1B5311840012F106 /* Decodable.swift in Sources */, + 8F27FAE61FA5757F00674C8B /* UnsafeKey.swift in Sources */, 17FB810F1B5311870012F106 /* Operators.swift in Sources */, 65DB18B11C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); @@ -528,7 +528,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 57FCDE5D1BA283C900130C48 /* Decodable.swift in Sources */, + 8F27FAE81FA5757F00674C8B /* UnsafeKey.swift in Sources */, 57FCDE5E1BA283C900130C48 /* Operators.swift in Sources */, 65DB18B31C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); @@ -538,7 +538,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8FE7B57E1B4CA01400837609 /* Decodable.swift in Sources */, + 8F27FAE51FA5757F00674C8B /* UnsafeKey.swift in Sources */, 8F956D1F1B4D6FF700243072 /* Operators.swift in Sources */, 65DB18B01C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); @@ -571,7 +571,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D0DC54771B78150900F79CB0 /* Decodable.swift in Sources */, + 8F27FAE71FA5757F00674C8B /* UnsafeKey.swift in Sources */, D0DC54781B78150900F79CB0 /* Operators.swift in Sources */, 65DB18B21C29AC0E003BDA5C /* RawRepresentableDecodable.swift in Sources */, ); diff --git a/Sources/Decodable.swift b/Sources/Decodable.swift deleted file mode 100644 index 549ddc4..0000000 --- a/Sources/Decodable.swift +++ /dev/null @@ -1,11 +0,0 @@ -// -// Decodable.swift -// Decodable -// -// Created by Johannes Lund on 2015-07-07. -// Copyright © 2015 anviking. All rights reserved. -// - -import Foundation - - diff --git a/Sources/Operators.swift b/Sources/Operators.swift index e842255..fb9d450 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -11,42 +11,70 @@ import Foundation // MARK: - Operators precedencegroup DecodingPrecedence { - associativity: right + associativity: left higherThan: CastingPrecedence } infix operator => : DecodingPrecedence infix operator =>? : DecodingPrecedence + + // Dict -> T func => (container: KeyedDecodingContainer, key: Key) throws -> A { - return try container.decode(A.self, forKey: key) + return try decode(container, key) } // Dict -> Dict func => (container: KeyedDecodingContainer, key: Key) throws -> KeyedDecodingContainer { - return try container.nestedContainer(keyedBy: Key.self, forKey: key) + return try nested(container, key) } // Dict -> Dict? func => (container: KeyedDecodingContainer, key: Key) throws -> KeyedDecodingContainer? { - if container.contains(key) { - return try container.nestedContainer(keyedBy: Key.self, forKey: key) - } else { - return nil - } + return try lift(nested)(container, key) } + + // Dict? -> Dict? func =>? (container: KeyedDecodingContainer?, key: Key) throws -> KeyedDecodingContainer? { - if let container = container, container.contains(key) { - return try container.nestedContainer(keyedBy: Key.self, forKey: key) - } else { - return nil - } + return try lift(nested)(container, key) } // Dict? -> Dict func => (container: KeyedDecodingContainer?, key: Key) throws -> KeyedDecodingContainer? { - return try container?.nestedContainer(keyedBy: Key.self, forKey: key) + return try container.map { try nested($0, key) } +} + +// Dict? -> T +func =>? (container: KeyedDecodingContainer?, key: Key) throws -> T? { + return try lift(decode)(container, key) +} + + + +// ------------------------- +// MARK: Private Helpers +// ------------------------- + + + + +private func decode(_ container: KeyedDecodingContainer, _ key: K) throws -> T { + return try container.decode(T.self, forKey: key) +} + +private func nested(_ container: KeyedDecodingContainer, _ key: K) throws -> KeyedDecodingContainer { + return try container.nestedContainer(keyedBy: K.self, forKey: key) +} + +private func lift(_ f: @escaping (KeyedDecodingContainer, K) throws -> T) -> (KeyedDecodingContainer?, K) throws -> T? { + return { container, key in + if let container = container, container.contains(key) { + return try f(container, key) + } else { + return nil + } + } } diff --git a/Sources/UnsafeKey.swift b/Sources/UnsafeKey.swift new file mode 100644 index 0000000..d43a652 --- /dev/null +++ b/Sources/UnsafeKey.swift @@ -0,0 +1,30 @@ +// +// UnsafeKey.swift +// Decodable +// +// Created by Johannes Lund on 2017-10-29. +// Copyright © 2017 anviking. All rights reserved. +// + +import Foundation + +struct UnsafeKey: CodingKey, ExpressibleByStringLiteral { + + let stringValue: String + + init(stringLiteral value: String) { + self.stringValue = value + } + init?(stringValue: String) { + self.stringValue = stringValue + } + + // MARK:- + + init?(intValue: Int) { + return nil + } + + var intValue: Int? { return nil } + +}