11import ExtrasJSON
22import Foundation
3+ import NIO
34
45/// `ExtendedJSONDecoder` facilitates the decoding of ExtendedJSON into `Decodable` values.
56public class ExtendedJSONDecoder {
@@ -42,19 +43,13 @@ public class ExtendedJSONDecoder {
4243 /// Initialize an `ExtendedJSONDecoder`.
4344 public init ( ) { }
4445
45- /// Decodes an instance of the requested type `T` from the provided extended JSON data.
46- /// - SeeAlso: https://docs.mongodb.com/manual/reference/mongodb-extended-json/
47- ///
48- /// - Parameters:
49- /// - type: Codable type to decode the input into.
50- /// - data: `Data` which represents the JSON that will be decoded.
51- /// - Returns: Decoded representation of the JSON input as an instance of `T`.
52- /// - Throws: `DecodingError` if the JSON data is corrupt or if any value throws an error during decoding.
53- public func decode< T: Decodable > ( _: T . Type , from data: Data ) throws -> T {
46+ private func decodeBytes< T: Decodable , C: Collection > ( _: T . Type , from bytes: C ) throws -> T
47+ where C. Element == UInt8
48+ {
5449 // Data --> JSONValue --> BSON --> T
5550 // Takes in JSON as `Data` encoded with `.utf8` and runs it through ExtrasJSON's parser to get an
5651 // instance of the `JSONValue` enum.
57- let json = try JSONParser ( ) . parse ( bytes: data )
52+ let json = try JSONParser ( ) . parse ( bytes: bytes )
5853
5954 // Then a `BSON` enum instance is decoded from the `JSONValue`.
6055 let bson = try self . decodeBSONFromJSON ( json, keyPath: [ ] )
@@ -65,6 +60,38 @@ public class ExtendedJSONDecoder {
6560 return try bsonDecoder. decode ( T . self, fromBSON: bson)
6661 }
6762
63+ /// Decodes an instance of the requested type `T` from the provided extended JSON data.
64+ /// - SeeAlso: https://docs.mongodb.com/manual/reference/mongodb-extended-json/
65+ ///
66+ /// - Parameters:
67+ /// - type: Codable type to decode the input into.
68+ /// - data: `Data` which represents the JSON that will be decoded.
69+ /// - Returns: Decoded representation of the JSON input as an instance of `T`.
70+ /// - Throws: `DecodingError` if the JSON data is corrupt or if any value throws an error during decoding.
71+ public func decode< T: Decodable > ( _: T . Type , from data: Data ) throws -> T {
72+ try self . decodeBytes ( T . self, from: data)
73+ }
74+
75+ /// Decodes an instance of the requested type `T` from the provided extended JSON data.
76+ /// - SeeAlso: https://docs.mongodb.com/manual/reference/mongodb-extended-json/
77+ ///
78+ /// - Parameters:
79+ /// - type: Codable type to decode the input into.
80+ /// - buffer: `ByteBuffer` which contains the JSON data that will be decoded.
81+ /// - Returns: Decoded representation of the JSON input as an instance of `T`.
82+ /// - Throws: `DecodingError` if the JSON data is corrupt or if any value throws an error during decoding.
83+ public func decode< T: Decodable > ( _: T . Type , from buffer: ByteBuffer ) throws -> T {
84+ guard buffer. readableBytes > 0 else {
85+ throw DecodingError . _extendedJSONError ( keyPath: [ ] , debugDescription: " empty buffer provided to decode " )
86+ }
87+
88+ var buffer = buffer
89+ // readBytes never returns nil here because we checked that the buffer wasn't empty and only read
90+ // readable bytes out from it.
91+ // swiftlint:disable:next force_unwrapping
92+ return try self . decodeBytes ( T . self, from: buffer. readBytes ( length: buffer. readableBytes) !)
93+ }
94+
6895 /// Decode a `BSON` from the given extended JSON.
6996 private func decodeBSONFromJSON( _ json: JSONValue , keyPath: [ String ] ) throws -> BSON {
7097 switch try self . decodeScalar ( json, keyPath: keyPath) {
0 commit comments