0001 // 0002 // JSONSubscripting.swift 0003 // Freddy 0004 // 0005 // Created by Zachary Waldowski on 8/15/15. 0006 // Copyright © 2015 Big Nerd Ranch. All rights reserved. 0007 // 0008 0009 // MARK: JSONPathType 0010 0011 /// A protocol used to define a path within an instance of `JSON` that leads to some desired value. 0012 /// 0013 /// A custom type, such as a `RawRepresentable` enum, may be made to conform to `JSONPathType` 0014 /// and used with the subscript APIs. 0015 public protocol JSONPathType{ 0016 /// Use `self` to key into a `dictionary`. 0017 /// 0018 /// Unlike Swift dictionaries, failing to find a value for a key should throw 0019 /// an error rather than convert to `nil`. 0020 /// 0021 /// Upon failure, implementers should throw an error from `JSON.Error`. 0022 func valueInDictionary
JSON.swift:40 case UnexpectedSubscript(type: JSONPathType.Type)JSONSubscripting.swift:33 extension JSONPathType {JSONSubscripting.swift:49 extension String: JSONPathType {JSONSubscripting.swift:64 extension Int: JSONPathType {JSONSubscripting.swift:84 case SubscriptIntoNull(JSONPathType)JSONSubscripting.swift:87 func valueForPathFragment(fragment: JSONPathType, detectNull: Swift.Bool) throws -> JSON {JSONSubscripting.swift:100 func valueAtPath(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> JSON {JSONSubscripting.swift:143 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> Decoded {JSONSubscripting.swift:152 public func double(path: JSONPathType...) throws -> Swift.Double {JSONSubscripting.swift:161 public func int(path: JSONPathType...) throws -> Swift.Int {JSONSubscripting.swift:170 public func string(path: JSONPathType...) throws -> Swift.String {JSONSubscripting.swift:179 public func bool(path: JSONPathType...) throws -> Swift.Bool {JSONSubscripting.swift:188 public func array(path: JSONPathType...) throws -> [JSON] {JSONSubscripting.swift:202 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Decoded] {JSONSubscripting.swift:211 public func dictionary(path: JSONPathType...) throws -> [Swift.String: JSON] {JSONSubscripting.swift:221 private func optionalAtPath(path: [JSONPathType], ifNotFound: Swift.Bool) throws -> JSON? {JSONSubscripting.swift:253 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {JSONSubscripting.swift:271 public func double(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Double? {JSONSubscripting.swift:289 public func int(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Int? {JSONSubscripting.swift:307 public func string(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.String? {JSONSubscripting.swift:325 public func bool(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Bool? {JSONSubscripting.swift:344 public func array(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [JSON]? {JSONSubscripting.swift:364 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Decoded]? {JSONSubscripting.swift:383 public func dictionary(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Swift.String: JSON]? {JSONSubscripting.swift:393 private func mapOptionalAtPath<Value>(path: [JSONPathType], @noescape fallback: () -> Value, @noescape transform: JSON throws -> Value) throws -> Value {JSONSubscripting.swift:407 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> Decoded) throws -> Decoded {JSONSubscripting.swift:417 public func double(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Double) throws -> Swift.Double {JSONSubscripting.swift:434 public func int(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Int) throws -> Swift.Int {JSONSubscripting.swift:451 public func string(path: JSONPathType..., @autoclosure or fallback: () -> Swift.String) throws -> Swift.String {JSONSubscripting.swift:468 public func bool(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Bool) throws -> Swift.Bool {JSONSubscripting.swift:485 public func array(path: JSONPathType..., @autoclosure or fallback: () -> [JSON]) throws -> [JSON] {JSONSubscripting.swift:504 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> [Decoded]) throws -> [Decoded] {JSONSubscripting.swift:522 public func dictionary(path: JSONPathType..., @autoclosure or fallback: () -> [Swift.String: JSON]) throws -> [Swift.String: JSON] {JSONSubscripting.swift:532 private func mapOptionalAtPath<Value>(path: [JSONPathType], ifNull: Swift.Bool, @noescape transform: JSON throws -> Value) throws -> Value? {JSONSubscripting.swift:562 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? {JSONSubscripting.swift:580 public func double(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Double? {JSONSubscripting.swift:598 public func int(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Int? {JSONSubscripting.swift:616 public func string(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.String? {JSONSubscripting.swift:634 public func bool(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Bool? {JSONSubscripting.swift:653 public func array(path: JSONPathType..., ifNull: Swift.Bool) throws -> [JSON]? {JSONSubscripting.swift:673 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Decoded]? {JSONSubscripting.swift:693 public func dictionary(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Swift.String: JSON]? {(dictionary: [Swift.String : JSON]) throws -> JSON 0023 0024 /// Use `self` to index into an `array`. 0025 /// 0026 /// Unlike Swift array, attempting to index outside the collection's bounds 0027 /// should throw an error rather than crash. 0028 /// 0029 /// Upon failure, implementers should throw an error from `JSON.Error`. 0030 func valueInArray
JSONSubscripting.swift:92 return try fragment.valueInDictionary(dict)(array: [JSON]) throws -> JSON 0031 } 0032 0033 extension JSONPathType { 0034 0035 /// The default behavior for keying into a dictionary is to throw 0036 /// `JSON.Error.UnexpectedSubscript`. 0037 public func valueInDictionary(dictionary: [Swift.String : JSON]) throws -> JSON { 0038 throw JSON.Error.UnexpectedSubscript(type: Self.self) 0039 } 0040 0041 /// The default behavior for indexing into an array is to throw 0042 /// `JSON.Error.UnexpectedSubscript`. 0043 public func valueInArray(array: [JSON]) throws -> JSON { 0044 throw JSON.Error.UnexpectedSubscript(type: Self.self) 0045 } 0046 0047 } 0048 0049 extension String: JSONPathType { 0050 0051 /// A method used to retrieve a value from a given dictionary for a specific key. 0052 /// - throws: `.KeyNotFound` with an associated value of `self`, where `self` is a `String`, 0053 /// should the key not be present within the `JSON`. 0054 /// - returns: The `JSON` value associated with the given key. 0055 public func valueInDictionary(dictionary: [Swift.String : JSON]) throws -> JSON { 0056 guard let next = dictionary[self] else { 0057 throw JSON.Error.KeyNotFound(key: self) 0058 } 0059 return next 0060 } 0061 0062 } 0063 0064 extension Int: JSONPathType { 0065 0066 /// A method used to retrieve a value from a given array for a specific index. 0067 /// - throws: `.IndexOutOfBounds` with an associated value of `self`, where `self` is an `Int`, 0068 /// should the index not be within the valid range for the array of `JSON`. 0069 /// - returns: The `JSON` value found at the given index. 0070 public func valueInArray(array: [JSON]) throws -> JSON { 0071 guard case array.indices = self else { 0072 throw JSON.Error.IndexOutOfBounds(index: self) 0073 } 0074 return array[self] 0075 } 0076 0077 } 0078 0079 // MARK: - Subscripting core 0080 0081 private extension JSON { 0082 0083 enum SubscriptError
JSONSubscripting.swift:94 return try fragment.valueInArray(array): ErrorType { 0084 case SubscriptIntoNull
JSONSubscripting.swift:90 throw SubscriptError.SubscriptIntoNull(fragment)(JSONPathType) 0085 } 0086 0087 func valueForPathFragment
JSONSubscripting.swift:90 throw SubscriptError.SubscriptIntoNull(fragment)JSONSubscripting.swift:228 } catch SubscriptError.SubscriptIntoNull(_ as Swift.String) where ifNotFound {JSONSubscripting.swift:230 } catch let SubscriptError.SubscriptIntoNull(fragment) {JSONSubscripting.swift:537 } catch SubscriptError.SubscriptIntoNull {(fragment: JSONPathType, detectNull: Swift.Bool) throws -> JSON { 0088 switch self { 0089 case .Null where detectNull: 0090 throw SubscriptError.SubscriptIntoNull(fragment) 0091 case let .Dictionary(dict): 0092 return try fragment.valueInDictionary(dict) 0093 case let .Array(array): 0094 return try fragment.valueInArray(array) 0095 default: 0096 throw Error.UnexpectedSubscript(type: fragment.dynamicType) 0097 } 0098 } 0099 0100 func valueAtPath
JSONSubscripting.swift:103 result = try result.valueForPathFragment(fragment, detectNull: detectNull)JSONSubscripting.swift:115 return try? valueForPathFragment(key, detectNull: false)JSONSubscripting.swift:119 return try? valueForPathFragment(index, detectNull: false)(path: [JSONPathType], detectNull: Swift.Bool = false) throws -> JSON { 0101 var result = self 0102 for fragment in path { 0103 result = try result.valueForPathFragment(fragment, detectNull: detectNull) 0104 } 0105 return result 0106 } 0107 0108 } 0109 0110 // MARK: - Subscripting operator 0111 0112 extension JSON { 0113 0114 public subscript(key: Swift.String) -> JSON? { 0115 return try? valueForPathFragment(key, detectNull: false) 0116 } 0117 0118 public subscript(index: Swift.Int) -> JSON? { 0119 return try? valueForPathFragment(index, detectNull: false) 0120 } 0121 0122 } 0123 0124 // MARK: - Simple member unpacking 0125 0126 extension JSON { 0127 0128 /// Attempts to decode into the returning type from a path into JSON. 0129 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`. 0130 /// - parameter type: If the context this method is called from does not 0131 /// make the return type clear, pass a type implementing `JSONDecodable` 0132 /// to disambiguate the type to decode with. 0133 /// - returns: An initialized member from the inner JSON. 0134 /// - throws: One of the following errors contained in `JSON.Error`: 0135 /// * `KeyNotFound`: A given `String` key does not exist inside a 0136 /// descendant `JSON` dictionary. 0137 /// * `IndexOutOfBounds`: A given `Int` index is outside the bounds of a 0138 /// descendant `JSON` array. 0139 /// * `UnexpectedSubscript`: A given subscript cannot be used with the 0140 /// corresponding `JSON` value. 0141 /// * `TypeNotConvertible`: The target value's type inside of 0142 /// the `JSON` instance does not match `Decoded`. 0143 public func decode
JSONSubscripting.swift:144 return try Decoded(json: valueAtPath(path))JSONSubscripting.swift:153 return try Swift.Double(json: valueAtPath(path))JSONSubscripting.swift:162 return try Swift.Int(json: valueAtPath(path))JSONSubscripting.swift:171 return try Swift.String(json: valueAtPath(path))JSONSubscripting.swift:180 return try Swift.Bool(json: valueAtPath(path))JSONSubscripting.swift:189 return try JSON.getArray(valueAtPath(path))JSONSubscripting.swift:203 return try JSON.getArrayOf(valueAtPath(path))JSONSubscripting.swift:212 return try JSON.getDictionary(valueAtPath(path))JSONSubscripting.swift:223 return try valueAtPath(path, detectNull: true)JSONSubscripting.swift:535 json = try valueAtPath(path, detectNull: ifNull)<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> Decoded { 0144 return try Decoded(json: valueAtPath(path)) 0145 } 0146 0147 /// Retrieves a `Double` from a path into JSON. 0148 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0149 /// - returns: A floating-point `Double` 0150 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0151 /// - seealso: `JSON.decode(_:type:)` 0152 public func double(path: JSONPathType...) throws -> Swift.Double { 0153 return try Swift.Double(json: valueAtPath(path)) 0154 } 0155 0156 /// Retrieves an `Int` from a path into JSON. 0157 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0158 /// - returns: A numeric `Int` 0159 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0160 /// - seealso: `JSON.decode(_:type:)` 0161 public func int(path: JSONPathType...) throws -> Swift.Int { 0162 return try Swift.Int(json: valueAtPath(path)) 0163 } 0164 0165 /// Retrieves a `String` from a path into JSON. 0166 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0167 /// - returns: A textual `String` 0168 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0169 /// - seealso: `JSON.decode(_:type:)` 0170 public func string
JSONDecodable.swift:102 let raw = try json.decode(type: RawValue.self)(path: JSONPathType...) throws -> Swift.String { 0171 return try Swift.String(json: valueAtPath(path)) 0172 } 0173 0174 /// Retrieves a `Bool` from a path into JSON. 0175 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0176 /// - returns: A truthy `Bool` 0177 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0178 /// - seealso: `JSON.decode(_:type:)` 0179 public func bool(path: JSONPathType...) throws -> Swift.Bool { 0180 return try Swift.Bool(json: valueAtPath(path)) 0181 } 0182 0183 /// Retrieves a `[JSON]` from a path into JSON. 0184 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0185 /// - returns: An `Array` of `JSON` elements 0186 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0187 /// - seealso: `JSON.decode(_:type:)` 0188 public func array(path: JSONPathType...) throws -> [JSON] { 0189 return try JSON.getArray(valueAtPath(path)) 0190 } 0191 0192 /// Attempts to decodes many values from a desendant JSON array at a path 0193 /// into JSON. 0194 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0195 /// - parameter type: If the context this method is called from does not 0196 /// make the return type clear, pass a type implementing `JSONDecodable` 0197 /// to disambiguate the type to decode with. 0198 /// - returns: An `Array` of decoded elements 0199 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`, or 0200 /// any error that arises from decoding the contained values. 0201 /// - seealso: `JSON.decode(_:type:)` 0202 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., type: Decoded.Type = Decoded.self) throws -> [Decoded] { 0203 return try JSON.getArrayOf(valueAtPath(path)) 0204 } 0205 0206 /// Retrieves a `[String: JSON]` from a path into JSON. 0207 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0208 /// - returns: An `Dictionary` of `String` mapping to `JSON` elements 0209 /// - throws: One of the `JSON.Error` cases thrown by `decode(_:type:)`. 0210 /// - seealso: `JSON.decode(_:type:)` 0211 public func dictionary(path: JSONPathType...) throws -> [Swift.String: JSON] { 0212 return try JSON.getDictionary(valueAtPath(path)) 0213 } 0214 0215 } 0216 0217 // MARK: - Missing-to-Optional unpacking 0218 0219 extension JSON { 0220 0221 private func optionalAtPath
JSONParser.swift:423 let key = try decodeString().string()(path: [JSONPathType], ifNotFound: Swift.Bool) throws -> JSON? { 0222 do { 0223 return try valueAtPath(path, detectNull: true) 0224 } catch Error.IndexOutOfBounds where ifNotFound { 0225 return nil 0226 } catch Error.KeyNotFound where ifNotFound { 0227 return nil 0228 } catch SubscriptError.SubscriptIntoNull(_ as Swift.String) where ifNotFound { 0229 return nil 0230 } catch let SubscriptError.SubscriptIntoNull(fragment) { 0231 throw Error.UnexpectedSubscript(type: fragment.dynamicType) 0232 } 0233 } 0234 0235 /// Optionally decodes into the returning type from a path into JSON. 0236 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0237 /// - parameter ifNotFound: If `true`, missing key or index errors are 0238 /// treated as `nil`. 0239 /// - parameter type: If the context this method is called from does not 0240 /// make the return type clear, pass a type implementing `JSONDecodable` 0241 /// to disambiguate the type to decode with. 0242 /// - returns: A decoded value from the inner JSON if found, or `nil`. 0243 /// - throws: One of the following errors contained in `JSON.Error`: 0244 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0245 /// corresponding `JSON` value. 0246 /// * If `ifNotFound` is `false`, `KeyNotFound`: A key `path` does not 0247 /// exist inside a descendant `JSON` dictionary. 0248 /// * If `ifNotFound` is `false`, `IndexOutOfBounds`: An index `path` is 0249 /// outside the bounds of a descendant `JSON` array. 0250 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0251 /// instance does not match the decoded value. 0252 /// * Any error that arises from decoding the value. 0253 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? { 0254 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Decoded.init) 0255 } 0256 0257 /// Optionally retrieves a `Double` from a path into JSON. 0258 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0259 /// - parameter ifNotFound: If `true`, missing key or index errors are 0260 /// treated as `nil`. 0261 /// - returns: A `Double` if a value could be found, otherwise `nil`. 0262 /// - throws: One of the following errors contained in `JSON.Error`: 0263 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0264 /// `JSON` dictionary. 0265 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0266 /// descendant `JSON` array. 0267 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0268 /// corresponding `JSON` value. 0269 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0270 /// instance does not match the decoded value. 0271 public func double(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Double? { 0272 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Double.init) 0273 } 0274 0275 /// Optionally retrieves a `Int` from a path into JSON. 0276 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0277 /// - parameter ifNotFound: If `true`, missing key or index errors are 0278 /// treated as `nil`. 0279 /// - returns: A numeric `Int` if a value could be found, otherwise `nil`. 0280 /// - throws: One of the following errors contained in `JSON.Error`: 0281 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0282 /// `JSON` dictionary. 0283 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0284 /// descendant `JSON` array. 0285 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0286 /// corresponding `JSON` value. 0287 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0288 /// instance does not match the decoded value. 0289 public func int(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Int? { 0290 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Int.init) 0291 } 0292 0293 /// Optionally retrieves a `String` from a path into JSON. 0294 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0295 /// - parameter ifNotFound: If `true`, missing key or index errors are 0296 /// treated as `nil`. 0297 /// - returns: A text `String` if a value could be found, otherwise `nil`. 0298 /// - throws: One of the following errors contained in `JSON.Error`: 0299 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0300 /// `JSON` dictionary. 0301 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0302 /// descendant `JSON` array. 0303 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0304 /// corresponding `JSON` value. 0305 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0306 /// instance does not match the decoded value. 0307 public func string(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.String? { 0308 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.String.init) 0309 } 0310 0311 /// Optionally retrieves a `Bool` from a path into JSON. 0312 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0313 /// - parameter ifNotFound: If `true`, missing key or index errors are 0314 /// treated as `nil`. 0315 /// - returns: A truthy `Bool` if a value could be found, otherwise `nil`. 0316 /// - throws: One of the following errors contained in `JSON.Error`: 0317 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0318 /// `JSON` dictionary. 0319 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0320 /// descendant `JSON` array. 0321 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0322 /// corresponding `JSON` value. 0323 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0324 /// instance does not match the decoded value. 0325 public func bool(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> Swift.Bool? { 0326 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Bool.init) 0327 } 0328 0329 /// Optionally retrieves a `[JSON]` from a path into JSON. 0330 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0331 /// - parameter ifNotFound: If `true`, missing key or index errors are 0332 /// treated as `nil`. 0333 /// - returns: An `Array` of `JSON` elements if a value could be found, 0334 /// otherwise `nil`. 0335 /// - throws: One of the following errors contained in `JSON.Error`: 0336 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0337 /// `JSON` dictionary. 0338 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0339 /// descendant `JSON` array. 0340 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0341 /// corresponding `JSON` value. 0342 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0343 /// instance does not match the decoded value. 0344 public func array(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [JSON]? { 0345 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getArray) 0346 } 0347 0348 /// Optionally decodes many values from a descendant array at a path into 0349 /// JSON. 0350 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0351 /// - parameter ifNotFound: If `true`, missing key or index errors are 0352 /// treated as `nil`. 0353 /// - returns: An `Array` of decoded elements if found, otherwise `nil`. 0354 /// - throws: One of the following errors contained in `JSON.Error`: 0355 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0356 /// `JSON` dictionary. 0357 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0358 /// descendant `JSON` array. 0359 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0360 /// corresponding `JSON` value. 0361 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0362 /// instance does not match the decoded value. 0363 /// * Any error that arises from decoding the value. 0364 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Decoded]? { 0365 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getArrayOf) 0366 } 0367 0368 /// Optionally retrieves a `[String: JSON]` from a path into JSON. 0369 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0370 /// - parameter ifNotFound: If `true`, missing key or index errors are 0371 /// treated as `nil`. 0372 /// - returns: A `Dictionary` of `String` mapping to `JSON` elements if a 0373 /// value could be found, otherwise `nil`. 0374 /// - throws: One of the following errors contained in `JSON.Error`: 0375 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0376 /// `JSON` dictionary. 0377 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0378 /// descendant `JSON` array. 0379 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0380 /// corresponding `JSON` value. 0381 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0382 /// instance does not match the decoded value. 0383 public func dictionary(path: JSONPathType..., ifNotFound: Swift.Bool) throws -> [Swift.String: JSON]? { 0384 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getDictionary) 0385 } 0386 0387 } 0388 0389 // MARK: - Missing-with-fallback unpacking 0390 0391 extension JSON { 0392 0393 private func mapOptionalAtPath
JSONSubscripting.swift:254 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Decoded.init)JSONSubscripting.swift:272 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Double.init)JSONSubscripting.swift:290 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Int.init)JSONSubscripting.swift:308 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.String.init)JSONSubscripting.swift:326 return try optionalAtPath(path, ifNotFound: ifNotFound).map(Swift.Bool.init)JSONSubscripting.swift:345 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getArray)JSONSubscripting.swift:365 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getArrayOf)JSONSubscripting.swift:384 return try optionalAtPath(path, ifNotFound: ifNotFound).map(JSON.getDictionary)JSONSubscripting.swift:394 return try optionalAtPath(path, ifNotFound: true).map(transform) ?? fallback()<Value>(path: [JSONPathType], @noescape fallback: () -> Value, @noescape transform: JSON throws -> Value) throws -> Value { 0394 return try optionalAtPath(path, ifNotFound: true).map(transform) ?? fallback() 0395 } 0396 0397 /// Attempts to decode into the returning type from a path into 0398 /// JSON, or returns a fallback if not found. 0399 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0400 /// - parameter fallback: Value to use when one is missing at the subscript. 0401 /// - returns: An initialized member from the inner JSON. 0402 /// - throws: One of the following errors contained in `JSON.Error`: 0403 /// * `UnexpectedSubscript`: A given subscript cannot be used with the 0404 /// corresponding `JSON` value. 0405 /// * `TypeNotConvertible`: The target value's type inside of 0406 /// the `JSON` instance does not match `Decoded`. 0407 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> Decoded) throws -> Decoded { 0408 return try mapOptionalAtPath(path, fallback: fallback, transform: Decoded.init) 0409 } 0410 0411 /// Retrieves a `Double` from a path into JSON or a fallback if not found. 0412 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0413 /// - parameter fallback: Array to use when one is missing at the subscript. 0414 /// - returns: A floating-point `Double` 0415 /// - throws: One of the `JSON.Error` cases thrown by calling `mapOptionalAtPath(_:fallback:transform:)`. 0416 /// - seealso: `optionalAtPath(_:ifNotFound)`. 0417 public func double(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Double) throws -> Swift.Double { 0418 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Double.init) 0419 } 0420 0421 /// Retrieves an `Int` from a path into JSON or a fallback if not found. 0422 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0423 /// - parameter fallback: Array to use when one is missing at the subscript. 0424 /// - returns: A numeric `Int` 0425 /// - throws: One of the following errors contained in `JSON.Error`: 0426 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0427 /// `JSON` dictionary. 0428 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0429 /// descendant `JSON` array. 0430 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0431 /// corresponding `JSON` value. 0432 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0433 /// instance does not match the decoded value. 0434 public func int(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Int) throws -> Swift.Int { 0435 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Int.init) 0436 } 0437 0438 /// Retrieves a `String` from a path into JSON or a fallback if not found. 0439 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0440 /// - parameter fallback: Array to use when one is missing at the subscript. 0441 /// - returns: A textual `String` 0442 /// - throws: One of the following errors contained in `JSON.Error`: 0443 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0444 /// `JSON` dictionary. 0445 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0446 /// descendant `JSON` array. 0447 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0448 /// corresponding `JSON` value. 0449 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0450 /// instance does not match the decoded value. 0451 public func string(path: JSONPathType..., @autoclosure or fallback: () -> Swift.String) throws -> Swift.String { 0452 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.String.init) 0453 } 0454 0455 /// Retrieves a `Bool` from a path into JSON or a fallback if not found. 0456 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0457 /// - parameter fallback: Array to use when one is missing at the subscript. 0458 /// - returns: A truthy `Bool` 0459 /// - throws: One of the following errors contained in `JSON.Error`: 0460 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0461 /// `JSON` dictionary. 0462 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0463 /// descendant `JSON` array. 0464 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0465 /// corresponding `JSON` value. 0466 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0467 /// instance does not match the decoded value. 0468 public func bool(path: JSONPathType..., @autoclosure or fallback: () -> Swift.Bool) throws -> Swift.Bool { 0469 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Bool.init) 0470 } 0471 0472 /// Retrieves a `[JSON]` from a path into JSON or a fallback if not found. 0473 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0474 /// - parameter fallback: Array to use when one is missing at the subscript. 0475 /// - returns: An `Array` of `JSON` elements 0476 /// - throws: One of the following errors contained in `JSON.Error`: 0477 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0478 /// `JSON` dictionary. 0479 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0480 /// descendant `JSON` array. 0481 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0482 /// corresponding `JSON` value. 0483 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0484 /// instance does not match the decoded value. 0485 public func array(path: JSONPathType..., @autoclosure or fallback: () -> [JSON]) throws -> [JSON] { 0486 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArray) 0487 } 0488 0489 /// Attempts to decodes many values from a desendant JSON array at a path 0490 /// into the recieving structure, returning a fallback if not found. 0491 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0492 /// - parameter fallback: Array to use when one is missing at the subscript. 0493 /// - returns: An `Array` of decoded elements 0494 /// - throws: One of the following errors contained in `JSON.Error`: 0495 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0496 /// `JSON` dictionary. 0497 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0498 /// descendant `JSON` array. 0499 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0500 /// corresponding `JSON` value. 0501 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0502 /// instance does not match the decoded value. 0503 /// * Any error that arises from decoding the value. 0504 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., @autoclosure or fallback: () -> [Decoded]) throws -> [Decoded] { 0505 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArrayOf) 0506 } 0507 0508 /// Retrieves a `[String: JSON]` from a path into JSON or a fallback if not 0509 /// found. 0510 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0511 /// - parameter fallback: Value to use when one is missing at the subscript 0512 /// - returns: An `Dictionary` of `String` mapping to `JSON` elements 0513 /// - throws: One of the following errors contained in `JSON.Error`: 0514 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0515 /// `JSON` dictionary. 0516 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0517 /// descendant `JSON` array. 0518 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0519 /// corresponding `JSON` value. 0520 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0521 /// instance does not match the decoded value. 0522 public func dictionary(path: JSONPathType..., @autoclosure or fallback: () -> [Swift.String: JSON]) throws -> [Swift.String: JSON] { 0523 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getDictionary) 0524 } 0525 0526 } 0527 0528 // MARK: - Null-to-Optional unpacking 0529 0530 extension JSON { 0531 0532 private func mapOptionalAtPath
JSONSubscripting.swift:408 return try mapOptionalAtPath(path, fallback: fallback, transform: Decoded.init)JSONSubscripting.swift:418 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Double.init)JSONSubscripting.swift:435 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Int.init)JSONSubscripting.swift:452 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.String.init)JSONSubscripting.swift:469 return try mapOptionalAtPath(path, fallback: fallback, transform: Swift.Bool.init)JSONSubscripting.swift:486 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArray)JSONSubscripting.swift:505 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getArrayOf)JSONSubscripting.swift:523 return try mapOptionalAtPath(path, fallback: fallback, transform: JSON.getDictionary)<Value>(path: [JSONPathType], ifNull: Swift.Bool, @noescape transform: JSON throws -> Value) throws -> Value? { 0533 var json: JSON? 0534 do { 0535 json = try valueAtPath(path, detectNull: ifNull) 0536 return try json.map(transform) 0537 } catch SubscriptError.SubscriptIntoNull { 0538 return nil 0539 } catch Error.ValueNotConvertible where ifNull && json == .Null { 0540 return nil 0541 } 0542 } 0543 0544 /// Optionally decodes into the returning type from a path into JSON. 0545 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0546 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0547 /// as `nil`. 0548 /// - parameter type: If the context this method is called from does not 0549 /// make the return type clear, pass a type implementing `JSONDecodable` 0550 /// to disambiguate the type to decode with. 0551 /// - returns: A decoded value from the inner JSON if found, or `nil`. 0552 /// - throws: One of the following errors contained in `JSON.Error`: 0553 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0554 /// `JSON` dictionary. 0555 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0556 /// descendant `JSON` array. 0557 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0558 /// corresponding `JSON` value. 0559 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0560 /// instance does not match the decoded value. 0561 /// * Any error that arises from decoding the value. 0562 public func decode<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool, type: Decoded.Type = Decoded.self) throws -> Decoded? { 0563 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Decoded.init) 0564 } 0565 0566 /// Optionally retrieves a `Double` from a path into JSON. 0567 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`. 0568 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0569 /// as `nil`. 0570 /// - returns: A `Double` if a value could be found, otherwise `nil`. 0571 /// - throws: One of the following errors contained in `JSON.Error`: 0572 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0573 /// `JSON` dictionary. 0574 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0575 /// descendant `JSON` array. 0576 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0577 /// corresponding `JSON` value. 0578 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0579 /// instance does not match the decoded value. 0580 public func double(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Double? { 0581 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Double.init) 0582 } 0583 0584 /// Optionally retrieves a `Int` from a path into JSON. 0585 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0586 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0587 /// as `nil`. 0588 /// - returns: A numeric `Int` if a value could be found, otherwise `nil`. 0589 /// - throws: One of the following errors contained in `JSON.Error`: 0590 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0591 /// `JSON` dictionary. 0592 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0593 /// descendant `JSON` array. 0594 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0595 /// corresponding `JSON` value. 0596 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0597 /// instance does not match the decoded value. 0598 public func int(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Int? { 0599 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Int.init) 0600 } 0601 0602 /// Optionally retrieves a `String` from a path into JSON. 0603 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0604 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0605 /// as `nil`. 0606 /// - returns: A text `String` if a value could be found, otherwise `nil`. 0607 /// - throws: One of the following errors contained in `JSON.Error`: 0608 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0609 /// `JSON` dictionary. 0610 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0611 /// descendant `JSON` array. 0612 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0613 /// corresponding `JSON` value. 0614 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0615 /// instance does not match the decoded value. 0616 public func string(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.String? { 0617 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.String.init) 0618 } 0619 0620 /// Optionally retrieves a `Bool` from a path into JSON. 0621 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0622 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0623 /// as `nil`. 0624 /// - returns: A truthy `Bool` if a value could be found, otherwise `nil`. 0625 /// - throws: One of the following errors contained in `JSON.Error`: 0626 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0627 /// `JSON` dictionary. 0628 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0629 /// descendant `JSON` array. 0630 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0631 /// corresponding `JSON` value. 0632 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0633 /// instance does not match the decoded value. 0634 public func bool(path: JSONPathType..., ifNull: Swift.Bool) throws -> Swift.Bool? { 0635 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Bool.init) 0636 } 0637 0638 /// Optionally retrieves a `[JSON]` from a path into the recieving structure. 0639 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0640 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0641 /// as `nil`. 0642 /// - returns: An `Array` of `JSON` elements if a value could be found, 0643 /// otherwise `nil`. 0644 /// - throws: One of the following errors contained in `JSON.Error`: 0645 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0646 /// `JSON` dictionary. 0647 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0648 /// descendant `JSON` array. 0649 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0650 /// corresponding `JSON` value. 0651 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0652 /// instance does not match the decoded value. 0653 public func array(path: JSONPathType..., ifNull: Swift.Bool) throws -> [JSON]? { 0654 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getArray) 0655 } 0656 0657 /// Optionally decodes many values from a descendant array at a path into 0658 /// JSON. 0659 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0660 /// - parameter ifNotFound: If `true`, missing key or index errors are 0661 /// treated as `nil`. 0662 /// - returns: An `Array` of decoded elements if found, otherwise `nil`. 0663 /// - throws: One of the following errors contained in `JSON.Error`: 0664 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0665 /// `JSON` dictionary. 0666 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0667 /// descendant `JSON` array. 0668 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0669 /// corresponding `JSON` value. 0670 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0671 /// instance does not match the decoded value. 0672 /// * Any error that arises from decoding the value. 0673 public func arrayOf<Decoded: JSONDecodable>(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Decoded]? { 0674 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getArrayOf) 0675 } 0676 0677 /// Optionally retrieves a `[String: JSON]` from a path into the recieving 0678 /// structure. 0679 /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON` 0680 /// - parameter ifNull: If `true`, target values matching `Null` are treated 0681 /// as `nil`. 0682 /// - returns: A `Dictionary` of `String` mapping to `JSON` elements if a 0683 /// value could be found, otherwise `nil`. 0684 /// - throws: One of the following errors contained in `JSON.Error`: 0685 /// * `KeyNotFound`: A key `path` does not exist inside a descendant 0686 /// `JSON` dictionary. 0687 /// * `IndexOutOfBounds`: An index `path` is outside the bounds of a 0688 /// descendant `JSON` array. 0689 /// * `UnexpectedSubscript`: A `path` item cannot be used with the 0690 /// corresponding `JSON` value. 0691 /// * `TypeNotConvertible`: The target value's type inside of the `JSON` 0692 /// instance does not match the decoded value. 0693 public func dictionary(path: JSONPathType..., ifNull: Swift.Bool) throws -> [Swift.String: JSON]? { 0694 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getDictionary) 0695 } 0696 0697 } 0698
JSONSubscripting.swift:563 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Decoded.init)JSONSubscripting.swift:581 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Double.init)JSONSubscripting.swift:599 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Int.init)JSONSubscripting.swift:617 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.String.init)JSONSubscripting.swift:635 return try mapOptionalAtPath(path, ifNull: ifNull, transform: Swift.Bool.init)JSONSubscripting.swift:654 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getArray)JSONSubscripting.swift:674 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getArrayOf)JSONSubscripting.swift:694 return try mapOptionalAtPath(path, ifNull: ifNull, transform: JSON.getDictionary)