Skip to content

Commit 05b7156

Browse files
authored
SWIFT-920 Support Decoding from BSON in BSONDecoder (#26)
1 parent aa44622 commit 05b7156

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

Sources/BSON/BSONDecoder.swift

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,7 @@ public class BSONDecoder {
139139
if let doc = document as? T {
140140
return doc
141141
}
142-
let _decoder = _BSONDecoder(referencing: .document(document), options: self.options)
143-
do {
144-
return try type.init(from: _decoder)
145-
} catch let error as BSONErrorProtocol {
146-
let unknownErrorMessage = "Unknown Error occurred while decoding BSON"
147-
throw DecodingError.dataCorrupted(
148-
DecodingError.Context(
149-
codingPath: [],
150-
debugDescription: "Unable to decode BSON: \(error.errorDescription ?? unknownErrorMessage)"
151-
)
152-
)
153-
}
142+
return try self.decode(type, fromBSON: BSON.document(document))
154143
}
155144

156145
/**
@@ -165,6 +154,29 @@ public class BSONDecoder {
165154
try self.decode(type, from: BSONDocument(fromBSON: data))
166155
}
167156

157+
/**
158+
* Decodes a top-level value of the given type from the given BSON.
159+
*
160+
* - Parameter type: The type of the value to decode.
161+
* - Parameter document: The BSON to decode from.
162+
* - Returns: A value of the requested type.
163+
* - Throws: `DecodingError` if any value throws an error during decoding.
164+
*/
165+
internal func decode<T: Decodable>(_ type: T.Type, fromBSON bson: BSON) throws -> T {
166+
let _decoder = _BSONDecoder(referencing: bson, options: self.options)
167+
do {
168+
return try _decoder.unbox(bson, as: type)
169+
} catch let error as BSONErrorProtocol {
170+
let unknownErrorMessage = "Unknown Error occurred while decoding BSON"
171+
throw DecodingError.dataCorrupted(
172+
DecodingError.Context(
173+
codingPath: _decoder.codingPath,
174+
debugDescription: "Unable to decode BSON: \(error.errorDescription ?? unknownErrorMessage)"
175+
)
176+
)
177+
}
178+
}
179+
168180
// TODO: SWIFT-930 Implement this
169181
// /**
170182
// * Decodes a top-level value of the given type from the given JSON/extended JSON string.

Tests/BSONTests/CodecTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ final class CodecTests: BSONTestCase {
4141
let s: NestedStruct
4242
}
4343

44+
/// Test decoding non-document BSON
45+
func testAnyBSON() throws {
46+
let decoder = BSONDecoder()
47+
expect(try decoder.decode(Int32.self, fromBSON: BSON.int32(1))).to(equal(1))
48+
let oid = try BSONObjectID("507f1f77bcf86cd799439011")
49+
expect(try decoder.decode(BSONObjectID.self, fromBSON: BSON.objectID(oid)))
50+
.to(equal(oid))
51+
expect(try decoder.decode(Array.self, fromBSON: [BSON.int32(1), BSON.int32(2)]))
52+
.to(equal([1, 2]))
53+
}
54+
4455
/// Test encoding/decoding a variety of structs containing simple types that have
4556
/// built in Codable support (strings, arrays, ints, and structs composed of them.)
4657
func testStructs() throws {

0 commit comments

Comments
 (0)