|
|
@@ -1251,9 +1251,15 @@ fileprivate class __JSONDecoder : Decoder {
|
|
|
DecodingError.Context(codingPath: self.codingPath,
|
|
|
debugDescription: "Cannot get keyed decoding container -- found null value instead."))
|
|
|
}
|
|
|
-
|
|
|
- guard let topContainer = self.storage.topContainer as? [String : Any] else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: self.storage.topContainer)
|
|
|
+ var topContainer : [String : Any]
|
|
|
+ if let rcValue = self.storage.topContainer as? FirebaseRemoteConfigValueDecoding,
|
|
|
+ let top = rcValue.jsonValue() {
|
|
|
+ topContainer = top
|
|
|
+ } else {
|
|
|
+ guard let top = self.storage.topContainer as? [String : Any] else {
|
|
|
+ throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: self.storage.topContainer)
|
|
|
+ }
|
|
|
+ topContainer = top
|
|
|
}
|
|
|
|
|
|
let container = _JSONKeyedDecodingContainer<Key>(referencing: self, wrapping: topContainer)
|
|
|
@@ -2118,6 +2124,9 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Bool.Type) throws -> Bool? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
+ if let rcValue = value as? FirebaseRemoteConfigValueDecoding {
|
|
|
+ return rcValue.boolValue()
|
|
|
+ }
|
|
|
if let number = value as? NSNumber {
|
|
|
// TODO: Add a flag to coerce non-boolean numbers into Bools?
|
|
|
if number === kCFBooleanTrue as NSNumber {
|
|
|
@@ -2136,13 +2145,25 @@ extension __JSONDecoder {
|
|
|
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
}
|
|
|
|
|
|
- fileprivate func unbox(_ value: Any, as type: Int.Type) throws -> Int? {
|
|
|
- guard !(value is NSNull) else { return nil }
|
|
|
+ fileprivate func rcValNumberAdaptor(_ value: Any) -> Any {
|
|
|
+ if let rcValue = value as? FirebaseRemoteConfigValueDecoding {
|
|
|
+ return rcValue.numberValue()
|
|
|
+ }
|
|
|
+ return value
|
|
|
+ }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
+ fileprivate func getNumber(_ value: Any, as type: Any.Type) throws -> NSNumber {
|
|
|
+ let val = rcValNumberAdaptor(value)
|
|
|
+ guard let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
+ throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: val)
|
|
|
}
|
|
|
+ return number
|
|
|
+ }
|
|
|
|
|
|
+ fileprivate func unbox(_ value: Any, as type: Int.Type) throws -> Int? {
|
|
|
+ guard !(value is NSNull) else { return nil }
|
|
|
+
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let int = number.intValue
|
|
|
guard NSNumber(value: int) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2154,10 +2175,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Int8.Type) throws -> Int8? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let int8 = number.int8Value
|
|
|
guard NSNumber(value: int8) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2169,10 +2187,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Int16.Type) throws -> Int16? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let int16 = number.int16Value
|
|
|
guard NSNumber(value: int16) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2184,10 +2199,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Int32.Type) throws -> Int32? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let int32 = number.int32Value
|
|
|
guard NSNumber(value: int32) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2199,10 +2211,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Int64.Type) throws -> Int64? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let int64 = number.int64Value
|
|
|
guard NSNumber(value: int64) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2214,10 +2223,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: UInt.Type) throws -> UInt? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let uint = number.uintValue
|
|
|
guard NSNumber(value: uint) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2229,10 +2235,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: UInt8.Type) throws -> UInt8? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let uint8 = number.uint8Value
|
|
|
guard NSNumber(value: uint8) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2244,10 +2247,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: UInt16.Type) throws -> UInt16? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let uint16 = number.uint16Value
|
|
|
guard NSNumber(value: uint16) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2259,10 +2259,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: UInt32.Type) throws -> UInt32? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let uint32 = number.uint32Value
|
|
|
guard NSNumber(value: uint32) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2274,10 +2271,7 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: UInt64.Type) throws -> UInt64? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
|
|
|
- throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
- }
|
|
|
-
|
|
|
+ let number = try getNumber(value, as: type)
|
|
|
let uint64 = number.uint64Value
|
|
|
guard NSNumber(value: uint64) == number else {
|
|
|
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type)."))
|
|
|
@@ -2289,7 +2283,8 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Float.Type) throws -> Float? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
|
|
|
+ let val = rcValNumberAdaptor(value)
|
|
|
+ if let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
|
|
|
// We are willing to return a Float by losing precision:
|
|
|
// * If the original value was integral,
|
|
|
// * and the integral value was > Float.greatestFiniteMagnitude, we will fail
|
|
|
@@ -2318,7 +2313,7 @@ extension __JSONDecoder {
|
|
|
overflow = true
|
|
|
*/
|
|
|
|
|
|
- } else if let string = value as? String,
|
|
|
+ } else if let string = val as? String,
|
|
|
case .convertFromString(let posInfString, let negInfString, let nanString) = self.options.nonConformingFloatDecodingStrategy {
|
|
|
if string == posInfString {
|
|
|
return Float.infinity
|
|
|
@@ -2335,7 +2330,8 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Double.Type) throws -> Double? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
- if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
|
|
|
+ let val = rcValNumberAdaptor(value)
|
|
|
+ if let number = val as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse {
|
|
|
// We are always willing to return the number as a Double:
|
|
|
// * If the original value was integral, it is guaranteed to fit in a Double; we are willing to lose precision past 2^53 if you encoded a UInt64 but requested a Double
|
|
|
// * If it was a Float or Double, you will get back the precise value
|
|
|
@@ -2353,7 +2349,7 @@ extension __JSONDecoder {
|
|
|
overflow = true
|
|
|
*/
|
|
|
|
|
|
- } else if let string = value as? String,
|
|
|
+ } else if let string = val as? String,
|
|
|
case .convertFromString(let posInfString, let negInfString, let nanString) = self.options.nonConformingFloatDecodingStrategy {
|
|
|
if string == posInfString {
|
|
|
return Double.infinity
|
|
|
@@ -2370,6 +2366,9 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: String.Type) throws -> String? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
+ if let rcValue = value as? FirebaseRemoteConfigValueDecoding {
|
|
|
+ return rcValue.stringValue()
|
|
|
+ }
|
|
|
guard let string = value as? String else {
|
|
|
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
|
|
|
}
|
|
|
@@ -2424,6 +2423,10 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Data.Type) throws -> Data? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
+ if let rcValue = value as? FirebaseRemoteConfigValueDecoding {
|
|
|
+ return rcValue.dataValue()
|
|
|
+ }
|
|
|
+
|
|
|
switch self.options.dataDecodingStrategy {
|
|
|
case .deferredToData:
|
|
|
self.storage.push(container: value)
|
|
|
@@ -2451,11 +2454,13 @@ extension __JSONDecoder {
|
|
|
fileprivate func unbox(_ value: Any, as type: Decimal.Type) throws -> Decimal? {
|
|
|
guard !(value is NSNull) else { return nil }
|
|
|
|
|
|
+ let val = rcValNumberAdaptor(value)
|
|
|
+
|
|
|
// Attempt to bridge from NSDecimalNumber.
|
|
|
- if let decimal = value as? Decimal {
|
|
|
+ if let decimal = val as? Decimal {
|
|
|
return decimal
|
|
|
} else {
|
|
|
- let doubleValue = try self.unbox(value, as: Double.self)!
|
|
|
+ let doubleValue = try self.unbox(val, as: Double.self)!
|
|
|
return Decimal(doubleValue)
|
|
|
}
|
|
|
}
|