@@ -190,19 +190,19 @@ extension Document: Sequence {
190190 *
191191 * - Parameters:
192192 * - maxSplits: The maximum number of times to split the document, or one less than the number of subsequences to
193- * return. If `maxSplits` + 1 subsequences are returned, the last one is a suffix of the original
193+ * return. If `maxSplits` + 1 subsequences are returned, the last one is a suffix of the original
194194 * document containing the remaining key-value pairs. `maxSplits` must be greater than or equal to
195195 * zero. The default value is `Int.max`.
196- * - omittingEmptySubsequences: If false, an empty document is returned in the result for each pair of
196+ * - omittingEmptySubsequences: If false, an empty document is returned in the result for each pair of
197197 * consecutive key-value pairs satisfying the `isSeparator` predicate and for each
198- * key-value pair at the start or end of the document satisfying the `isSeparator`
198+ * key-value pair at the start or end of the document satisfying the `isSeparator`
199199 * predicate. If true, only nonempty documents are returned. The default value is
200200 * true.
201201 * - isSeparator: A closure that returns true if its argument should be used to split the document and otherwise
202202 * returns false.
203203 *
204204 * - Returns: An array of documents, split from this document's key-value pairs.
205- */
205+ */
206206 public func split( maxSplits: Int = Int . max,
207207 omittingEmptySubsequences: Bool = true ,
208208 whereSeparator isSeparator: ( KeyValuePair ) throws -> Bool ) rethrows -> [ Document ] {
@@ -226,7 +226,7 @@ extension Document: Sequence {
226226}
227227
228228extension Document {
229- // this is an alternative to the built-in `Document.filter` that returns an `[KeyValuePair]`.
229+ // this is an alternative to the built-in `Document.filter` that returns an `[KeyValuePair]`.
230230 // this variant is called by default, but the other is still accessible by explicitly stating
231231 // return type: `let newDocPairs: [Document.KeyValuePair] = newDoc.filter { ... }`
232232 /**
@@ -248,166 +248,3 @@ extension Document {
248248 return output
249249 }
250250}
251-
252- /// An iterator over the values in a `Document`.
253- public class DocumentIterator : IteratorProtocol {
254- /// the libbson iterator. it must be a `var` because we use it as
255- /// an inout argument
256- internal var iter : bson_iter_t
257- /// a reference to the storage for the document we're iterating
258- internal let storage : DocumentStorage
259-
260- /// Initializes a new iterator over the contents of `doc`. Returns `nil` if the key is not
261- /// found, or if an iterator cannot be created over `doc` due to an error from e.g. corrupt data.
262- internal init ? ( forDocument doc: Document ) {
263- self . iter = bson_iter_t ( )
264- self . storage = doc. storage
265- guard bson_iter_init ( & self . iter, doc. data) else {
266- return nil
267- }
268- }
269-
270- /// Initializes a new iterator over the contents of `doc`. Returns `nil` if an iterator cannot
271- /// be created over `doc` due to an error from e.g. corrupt data, or if the key is not found.
272- internal init ? ( forDocument doc: Document , advancedTo key: String ) {
273- self . iter = bson_iter_t ( )
274- self . storage = doc. storage
275- guard bson_iter_init_find ( & iter, doc. data, key. cString ( using: . utf8) ) else {
276- return nil
277- }
278- }
279-
280- /// Advances the iterator forward one value. Returns false if there is an error moving forward
281- /// or if at the end of the document. Returns true otherwise.
282- internal func advance( ) -> Bool {
283- return bson_iter_next ( & self . iter)
284- }
285-
286- /// Moves the iterator to the specified key. Returns false if the key does not exist. Returns true otherwise.
287- internal func move( to key: String ) -> Bool {
288- return bson_iter_find ( & self . iter, key. cString ( using: . utf8) )
289- }
290-
291- /// Returns the current key. Assumes the iterator is in a valid position.
292- internal var currentKey : String {
293- return String ( cString: bson_iter_key ( & self . iter) )
294- }
295-
296- /// Returns the current value. Assumes the iterator is in a valid position.
297- internal var currentValue : BSONValue {
298- do {
299- return try self . safeCurrentValue ( )
300- } catch { // Since properties cannot throw, we need to catch and raise a fatalError.
301- fatalError ( " Error getting current value from iterator: \( error) " )
302- }
303- }
304-
305- /// Returns the current value's type. Assumes the iterator is in a valid position.
306- internal var currentType : BSONType {
307- return BSONType ( rawValue: bson_iter_type ( & self . iter) . rawValue) ?? . invalid
308- }
309-
310- /// Returns the keys from the iterator's current position to the end. The iterator
311- /// will be exhausted after this property is accessed.
312- internal var keys : [ String ] {
313- var keys = [ String] ( )
314- while self . advance ( ) { keys. append ( self . currentKey) }
315- return keys
316- }
317-
318- /// Returns the values from the iterator's current position to the end. The iterator
319- /// will be exhausted after this property is accessed.
320- internal var values : [ BSONValue ] {
321- var values = [ BSONValue] ( )
322- while self . advance ( ) { values. append ( self . currentValue) }
323- return values
324- }
325-
326- /// Returns the current value (equivalent to the `currentValue` property) or throws on error.
327- ///
328- /// - Throws:
329- /// - `RuntimeError.internalError` if the current value of this `DocumentIterator` cannot be decoded to BSON.
330- internal func safeCurrentValue( ) throws -> BSONValue {
331- guard let bsonType = DocumentIterator . bsonTypeMap [ currentType] else {
332- throw RuntimeError . internalError (
333- message: " Unknown BSONType for iterator's current value with type: \( currentType) "
334- )
335- }
336-
337- return try bsonType. from ( iterator: self )
338- }
339-
340- // uses an iterator to copy (key, value) pairs of the provided document from range [startIndex, endIndex) into a new
341- // document. starts at the startIndex-th pair and ends at the end of the document or the (endIndex-1)th index,
342- // whichever comes first.
343- internal static func subsequence( of doc: Document , startIndex: Int = 0 , endIndex: Int = Int . max) -> Document {
344- guard endIndex >= startIndex else {
345- fatalError ( " endIndex must be >= startIndex " )
346- }
347-
348- guard let iter = DocumentIterator ( forDocument: doc) else {
349- return [ : ]
350- }
351-
352- // skip the values preceding startIndex. this is more performant than calling next, because
353- // it doesn't pull the unneeded key/values out of the iterator
354- for _ in 0 ..< startIndex { _ = iter. advance ( ) }
355-
356- var output = Document ( )
357-
358- // TODO SWIFT-224: use va_list variant of bson_copy_to_excluding to improve performance
359- for _ in startIndex..< endIndex {
360- if let next = iter. next ( ) {
361- output [ next. key] = next. value
362- } else {
363- // we ran out of values
364- break
365- }
366- }
367-
368- return output
369- }
370-
371- /// Returns the next value in the sequence, or `nil` if the iterator is exhausted.
372- public func next( ) -> Document . KeyValuePair ? {
373- return self . advance ( ) ? ( self . currentKey, self . currentValue) : nil
374- }
375-
376- /**
377- * Overwrites the current value of this `DocumentIterator` with the supplied value.
378- *
379- * - Throws:
380- * - `RuntimeError.internalError` if the new value is an `Int` and cannot be written to BSON.
381- * - `UserError.logicError` if the new value is a `Decimal128` or `ObjectId` and is improperly formatted.
382- */
383- internal func overwriteCurrentValue( with newValue: Overwritable ) throws {
384- guard newValue. bsonType == self . currentType else {
385- fatalError ( " Expected \( newValue) to have BSON type \( self . currentType) , but has type \( newValue. bsonType) " )
386- }
387- try newValue. writeToCurrentPosition ( of: self )
388- }
389-
390- private static let bsonTypeMap : [ BSONType : BSONValue . Type ] = [
391- . double: Double . self,
392- . string: String . self,
393- . document: Document . self,
394- . array: [ BSONValue ] . self,
395- . binary: Binary . self,
396- . objectId: ObjectId . self,
397- . boolean: Bool . self,
398- . dateTime: Date . self,
399- . regularExpression: RegularExpression . self,
400- . dbPointer: DBPointer . self,
401- . javascript: CodeWithScope . self,
402- . symbol: Symbol . self,
403- . javascriptWithScope: CodeWithScope . self,
404- . int32: Int . self,
405- . timestamp: Timestamp . self,
406- . int64: Int64 . self,
407- . decimal128: Decimal128 . self,
408- . minKey: MinKey . self,
409- . maxKey: MaxKey . self,
410- . null: BSONNull . self,
411- . undefined: BSONUndefined . self
412- ]
413- }
0 commit comments