Skip to content

Commit fe49ffc

Browse files
authored
SWIFT-924 Implement methods on BSONValues to convert to Extended JSON (#31)
1 parent 101ec2b commit fe49ffc

20 files changed

+310
-7
lines changed

Sources/BSON/Array+BSONValue.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ extension Array: BSONValue where Element == BSON {
2626
}
2727
}
2828

29+
/// Converts this `BSONArray` to a corresponding `JSON` in relaxed extendedJSON format.
30+
internal func toRelaxedExtendedJSON() -> JSON {
31+
.array(self.map { $0.toRelaxedExtendedJSON() })
32+
}
33+
34+
/// Converts this `BSONArray` to a corresponding `JSON` in canonical extendedJSON format.
35+
internal func toCanonicalExtendedJSON() -> JSON {
36+
.array(self.map { $0.toCanonicalExtendedJSON() })
37+
}
38+
2939
internal static var bsonType: BSONType { .array }
3040

3141
internal var bson: BSON { .array(self) }

Sources/BSON/BSON.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ public enum BSON {
111111
self = doc.bson
112112
}
113113

114+
/// Converts this `BSON` to a corresponding `JSON` in relaxed extendedJSON format.
115+
internal func toRelaxedExtendedJSON() -> JSON {
116+
self.bsonValue.toRelaxedExtendedJSON()
117+
}
118+
119+
/// Converts this `BSON` to a corresponding `JSON` in canonical extendedJSON format.
120+
internal func toCanonicalExtendedJSON() -> JSON {
121+
self.bsonValue.toCanonicalExtendedJSON()
122+
}
123+
114124
/// Get the `BSONType` of this `BSON`.
115125
public var type: BSONType {
116126
self.bsonValue.bsonType

Sources/BSON/BSONBinary.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,21 @@ extension BSONBinary: BSONValue {
198198
}
199199
}
200200

201+
/// Converts this `BSONBinary` to a corresponding `JSON` in relaxed extendedJSON format.
202+
internal func toRelaxedExtendedJSON() -> JSON {
203+
self.toCanonicalExtendedJSON()
204+
}
205+
206+
/// Converts this `BSONBinary` to a corresponding `JSON` in canonical extendedJSON format.
207+
internal func toCanonicalExtendedJSON() -> JSON {
208+
[
209+
"$binary": [
210+
"base64": .string(Data(self.data.readableBytesView).base64EncodedString()),
211+
"subType": .string(String(self.subtype.rawValue, radix: 16))
212+
]
213+
]
214+
}
215+
201216
internal static var bsonType: BSONType { .binary }
202217

203218
internal var bson: BSON { .binary(self) }

Sources/BSON/BSONCode.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ extension BSONCode: BSONValue {
7171
}
7272
}
7373

74+
/// Converts this `BSONCode` to a corresponding `JSON` in relaxed extendedJSON format.
75+
internal func toRelaxedExtendedJSON() -> JSON {
76+
self.toCanonicalExtendedJSON()
77+
}
78+
79+
/// Converts this `BSONCode` to a corresponding `JSON` in canonical extendedJSON format.
80+
internal func toCanonicalExtendedJSON() -> JSON {
81+
["$code": .string(self.code)]
82+
}
83+
7484
internal static var bsonType: BSONType { .code }
7585

7686
internal var bson: BSON { .code(self) }
@@ -128,6 +138,16 @@ extension BSONCodeWithScope: BSONValue {
128138
}
129139
}
130140

141+
/// Converts this `BSONCodeWithScope` to a corresponding `JSON` in relaxed extendedJSON format.
142+
internal func toRelaxedExtendedJSON() -> JSON {
143+
["$code": .string(self.code), "$scope": self.scope.toRelaxedExtendedJSON()]
144+
}
145+
146+
/// Converts this `BSONCodeWithScope` to a corresponding `JSON` in canonical extendedJSON format.
147+
internal func toCanonicalExtendedJSON() -> JSON {
148+
["$code": .string(self.code), "$scope": self.scope.toCanonicalExtendedJSON()]
149+
}
150+
131151
internal static var bsonType: BSONType { .codeWithScope }
132152

133153
internal var bson: BSON { .codeWithScope(self) }

Sources/BSON/BSONDBPointer.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ extension BSONDBPointer: BSONValue {
6666
self = BSONDBPointer(ref: refStr, id: oid)
6767
}
6868

69+
/// Converts this `BSONDBPointer` to a corresponding `JSON` in relaxed extendedJSON format.
70+
internal func toRelaxedExtendedJSON() -> JSON {
71+
self.toCanonicalExtendedJSON()
72+
}
73+
74+
/// Converts this `BSONDBPointer` to a corresponding `JSON` in canonical extendedJSON format.
75+
internal func toCanonicalExtendedJSON() -> JSON {
76+
[
77+
"$dbPointer": [
78+
"$ref": .string(self.ref),
79+
"$id": self.id.toCanonicalExtendedJSON()
80+
]
81+
]
82+
}
83+
6984
internal static var bsonType: BSONType { .dbPointer }
7085

7186
internal var bson: BSON { .dbPointer(self) }

Sources/BSON/BSONDecimal128.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,16 @@ extension BSONDecimal128: BSONValue {
509509
}
510510
}
511511

512+
/// Converts this `Decimal128` to a corresponding `JSON` in relaxed extendedJSON format.
513+
internal func toRelaxedExtendedJSON() -> JSON {
514+
self.toCanonicalExtendedJSON()
515+
}
516+
517+
/// Converts this `Decimal128` to a corresponding `JSON` in canonical extendedJSON format.
518+
internal func toCanonicalExtendedJSON() -> JSON {
519+
["$numberDecimal": .string(self.toString())]
520+
}
521+
512522
internal static var bsonType: BSONType { .decimal128 }
513523

514524
internal var bson: BSON { .decimal128(self) }

Sources/BSON/BSONDocument.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,24 @@ extension BSONDocument: BSONValue {
375375
self = BSONDocument(keyValuePairs: doc)
376376
}
377377

378+
/// Converts this `BSONDocument` to a corresponding `JSON` in relaxed extendedJSON format.
379+
internal func toRelaxedExtendedJSON() -> JSON {
380+
var obj: [String: JSON] = [:]
381+
for (key, value) in self {
382+
obj[key] = value.toRelaxedExtendedJSON()
383+
}
384+
return .object(obj)
385+
}
386+
387+
/// Converts this `BSONDocument` to a corresponding `JSON` in canonical extendedJSON format.
388+
internal func toCanonicalExtendedJSON() -> JSON {
389+
var obj: [String: JSON] = [:]
390+
for (key, value) in self {
391+
obj[key] = value.toCanonicalExtendedJSON()
392+
}
393+
return .object(obj)
394+
}
395+
378396
internal static var bsonType: BSONType { .document }
379397

380398
internal var bson: BSON { .document(self) }

Sources/BSON/BSONEncoder.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,14 @@ private class MutableArray: BSONValue {
770770
fatalError("MutableArray: BSONValue.init(fromExtJSON) should be unused")
771771
}
772772

773+
internal func toRelaxedExtendedJSON() -> JSON {
774+
fatalError("MutableArray: BSONValue.toRelaxedExtendedJSON() should be unused")
775+
}
776+
777+
internal func toCanonicalExtendedJSON() -> JSON {
778+
fatalError("MutableArray: BSONValue.toCanonicalExtendedJSON() should be unused")
779+
}
780+
773781
/// methods required by the BSONValue protocol that we don't actually need/use. MutableArray
774782
/// is just a BSONValue to simplify usage alongside true BSONValues within the encoder.
775783
static func read(from buffer: inout ByteBuffer) throws -> BSON {
@@ -858,6 +866,14 @@ private class MutableDictionary: BSONValue {
858866
fatalError("MutableDictionary: BSONValue.init(fromExtJSON) should be unused")
859867
}
860868

869+
internal func toRelaxedExtendedJSON() -> JSON {
870+
fatalError("MutableDictionary: BSONValue.toRelaxedExtendedJSON() should be unused")
871+
}
872+
873+
internal func toCanonicalExtendedJSON() -> JSON {
874+
fatalError("MutableDictionary: BSONValue.toCanonicalExtendedJSON() should be unused")
875+
}
876+
861877
/// methods required by the BSONValue protocol that we don't actually need/use. MutableDictionary
862878
/// is just a BSONValue to simplify usage alongside true BSONValues within the encoder.
863879
static func read(from buffer: inout ByteBuffer) throws -> BSON {

Sources/BSON/BSONNulls.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ internal struct BSONNull: BSONValue, Equatable {
2424
}
2525
}
2626

27+
/// Converts this `BSONNull` to a corresponding `JSON` in relaxed extendedJSON format.
28+
internal func toRelaxedExtendedJSON() -> JSON {
29+
self.toCanonicalExtendedJSON()
30+
}
31+
32+
/// Converts this `BSONNull` to a corresponding `JSON` in canonical extendedJSON format.
33+
internal func toCanonicalExtendedJSON() -> JSON {
34+
.null
35+
}
36+
2737
internal static var bsonType: BSONType { .null }
2838

2939
internal var bson: BSON { .null }
@@ -70,6 +80,16 @@ internal struct BSONUndefined: BSONValue, Equatable {
7080
self = BSONUndefined()
7181
}
7282

83+
/// Converts this `BSONUndefined` to a corresponding `JSON` in relaxed extendedJSON format.
84+
internal func toRelaxedExtendedJSON() -> JSON {
85+
self.toCanonicalExtendedJSON()
86+
}
87+
88+
/// Converts this `BSONUndefined` to a corresponding `JSON` in canonical extendedJSON format.
89+
internal func toCanonicalExtendedJSON() -> JSON {
90+
["$undefined": true]
91+
}
92+
7393
internal static var bsonType: BSONType { .undefined }
7494

7595
internal var bson: BSON { .undefined }
@@ -116,6 +136,16 @@ internal struct BSONMinKey: BSONValue, Equatable {
116136
self = BSONMinKey()
117137
}
118138

139+
/// Converts this `BSONMinKey` to a corresponding `JSON` in relaxed extendedJSON format.
140+
internal func toRelaxedExtendedJSON() -> JSON {
141+
self.toCanonicalExtendedJSON()
142+
}
143+
144+
/// Converts this `BSONMinKey` to a corresponding `JSON` in canonical extendedJSON format.
145+
internal func toCanonicalExtendedJSON() -> JSON {
146+
["$minKey": 1]
147+
}
148+
119149
internal static var bsonType: BSONType { .minKey }
120150

121151
internal var bson: BSON { .minKey }
@@ -162,6 +192,16 @@ internal struct BSONMaxKey: BSONValue, Equatable {
162192
self = BSONMaxKey()
163193
}
164194

195+
/// Converts this `BSONMaxKey` to a corresponding `JSON` in relaxed extendedJSON format.
196+
internal func toRelaxedExtendedJSON() -> JSON {
197+
self.toCanonicalExtendedJSON()
198+
}
199+
200+
/// Converts this `BSONMaxKey` to a corresponding `JSON` in canonical extendedJSON format.
201+
internal func toCanonicalExtendedJSON() -> JSON {
202+
["$maxKey": 1]
203+
}
204+
165205
internal static var bsonType: BSONType { .maxKey }
166206

167207
internal var bson: BSON { .maxKey }

Sources/BSON/BSONObjectID.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ public struct BSONObjectID: Equatable, Hashable, CustomStringConvertible {
6161
}
6262
self = BSONObjectID(data)
6363
}
64+
}
6465

66+
extension BSONObjectID: BSONValue {
6567
/*
6668
* Initializes an `ObjectID` from ExtendedJSON.
6769
*
@@ -97,9 +99,17 @@ public struct BSONObjectID: Equatable, Hashable, CustomStringConvertible {
9799
)
98100
}
99101
}
100-
}
101102

102-
extension BSONObjectID: BSONValue {
103+
/// Converts this `BSONObjectID` to a corresponding `JSON` in relaxed extendedJSON format.
104+
internal func toRelaxedExtendedJSON() -> JSON {
105+
self.toCanonicalExtendedJSON()
106+
}
107+
108+
/// Converts this `BSONObjectID` to a corresponding `JSON` in canonical extendedJSON format.
109+
internal func toCanonicalExtendedJSON() -> JSON {
110+
["$oid": .string(self.hex)]
111+
}
112+
103113
internal static var bsonType: BSONType { .objectID }
104114

105115
internal var bson: BSON { .objectID(self) }

0 commit comments

Comments
 (0)