Skip to content

Commit

Permalink
Added alternate encode/decode functions that use [String:Any].
Browse files Browse the repository at this point in the history
These just coerce the dictionaries at the moment, which isn't efficient. In theory we could have parallel implementations for both NSDictionary and Swift-dictionaries.
  • Loading branch information
samdeane committed Feb 20, 2018
1 parent 4a7966c commit 209a8b6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Sources/DictionaryCoding/DictionaryDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ open class DictionaryDecoder {
public init() {}

// MARK: - Decoding Values

/// Decodes a top-level value of the given type from the given Dictionary representation.
///
/// - parameter type: The type of the value to decode.
Expand All @@ -192,6 +193,23 @@ open class DictionaryDecoder {

return value
}

/// Decodes a top-level value of the given type from the given Dictionary representation.
///
/// - parameter type: The type of the value to decode.
/// - parameter data: The data to decode from.
/// - returns: A value of the requested type.
/// - throws: `DecodingError.dataCorrupted` if values requested from the payload are corrupted, or if the given data is not valid Dictionary.
/// - throws: An error if any value throws an error during decoding.
open func decode<T : Decodable>(_ type: T.Type, from dictionary: [String:Any]) throws -> T {
let decoder = _DictionaryDecoder(referencing: dictionary, options: self.options)
guard let value = try decoder.unbox(dictionary, as: type) else {
throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value."))
}

return value
}

}

// MARK: - _DictionaryDecoder
Expand Down
26 changes: 26 additions & 0 deletions Sources/DictionaryCoding/DictionaryEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,32 @@ open class DictionaryEncoder {

return topLevel as! NSDictionary
}

// MARK: - Encoding Values
/// Encodes the given top-level value and returns its Dictionary representation.
///
/// - parameter value: The value to encode.
/// - returns: A new `Data` value containing the encoded Dictionary data.
/// - throws: `EncodingError.invalidValue` if a non-conforming floating-point value is encountered during encoding, and the encoding strategy is `.throw`.
/// - throws: An error if any value throws an error during encoding.
open func encode<T : Encodable>(_ value: T) throws -> [String:Any] {
let encoder = _DictionaryEncoder(options: self.options)

guard let topLevel = try encoder.box_(value) else {
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) did not encode any values."))
}

if topLevel is NSNull {
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) encoded as null Dictionary fragment."))
} else if topLevel is NSNumber {
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) encoded as number Dictionary fragment."))
} else if topLevel is NSString {
throw EncodingError.invalidValue(value, EncodingError.Context(codingPath: [], debugDescription: "Top-level \(T.self) encoded as string Dictionary fragment."))
}

return topLevel as! [String:Any]
}

}

// MARK: - _DictionaryEncoder
Expand Down

0 comments on commit 209a8b6

Please sign in to comment.