Skip to content

Commit 49460e8

Browse files
committed
Vastly speed up Document encoding
1 parent caa0faa commit 49460e8

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

Sources/BSON/Codable/Encoding/BSONEncoder.swift

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public final class BSONEncoder {
2424

2525
try value.encode(to: encoder)
2626

27-
guard encoder.target == .document, let document = encoder.document else {
27+
guard case .document(let document) = encoder.target else {
2828
throw BSONEncoderError.encodableNotDocument
2929
}
3030

@@ -71,20 +71,39 @@ public final class BSONEncoder {
7171

7272
fileprivate final class _BSONEncoder: Encoder, AnyBSONEncoder {
7373
enum Target {
74-
case document
75-
case primitive
74+
case document(Document)
75+
case primitive(Primitive?)
7676
}
7777

7878
var target: Target?
7979
var document: Document? {
80-
didSet {
81-
writer?(document)
80+
get {
81+
switch target {
82+
case .document(let document):
83+
document
84+
case .primitive(let primitive):
85+
nil
86+
case nil:
87+
nil
88+
}
89+
}
90+
set {
91+
target = .document(newValue ?? [:])
8292
}
8393
}
84-
8594
var primitive: Primitive? {
86-
didSet {
87-
writer?(primitive)
95+
get {
96+
switch target {
97+
case .document(let document):
98+
document
99+
case .primitive(let primitive):
100+
primitive
101+
case nil:
102+
nil
103+
}
104+
}
105+
set {
106+
target = .primitive(newValue)
88107
}
89108
}
90109

@@ -107,9 +126,7 @@ fileprivate final class _BSONEncoder: Encoder, AnyBSONEncoder {
107126
}
108127

109128
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key: CodingKey {
110-
self.target = .document
111-
self.document = Document()
112-
129+
self.target = .document(Document())
113130
let container = _BSONKeyedEncodingContainer<Key>(
114131
encoder: self,
115132
codingPath: codingPath
@@ -119,8 +136,7 @@ fileprivate final class _BSONEncoder: Encoder, AnyBSONEncoder {
119136
}
120137

121138
func unkeyedContainer() -> UnkeyedEncodingContainer {
122-
self.target = .document
123-
self.document = Document()
139+
self.target = .document(Document())
124140

125141
return _BSONUnkeyedEncodingContainer(
126142
encoder: self,
@@ -129,7 +145,7 @@ fileprivate final class _BSONEncoder: Encoder, AnyBSONEncoder {
129145
}
130146

131147
func singleValueContainer() -> SingleValueEncodingContainer {
132-
self.target = .primitive
148+
self.target = .primitive(nil)
133149

134150
return _BSONSingleValueEncodingContainer(
135151
encoder: self,
@@ -139,7 +155,7 @@ fileprivate final class _BSONEncoder: Encoder, AnyBSONEncoder {
139155

140156
// MARK: Encoding
141157
func encode(document: Document) throws {
142-
self.document = document
158+
self.target = .document(document)
143159
}
144160

145161
subscript(key: CodingKey) -> Primitive? {

0 commit comments

Comments
 (0)