From 6484f4c4e4be51620cadea89e60df0cc7b096eb6 Mon Sep 17 00:00:00 2001 From: Dianna Ma Date: Tue, 19 Nov 2024 21:20:43 +0000 Subject: [PATCH] add dependency on swift-bson --- .../default/results.json | 1 - Benchmarks/Benchmarks/BSONEncoding/Main.swift | 47 -- .../Benchmarks/BSONEncoding/Scheme.swift | 146 ---- Benchmarks/Package.resolved | 140 ---- Benchmarks/Package.swift | 24 - Package.resolved | 23 +- Package.swift | 142 +--- Sources/BSON/README.md | 9 - Sources/BSON/exports.swift | 3 - Sources/BSONABI/BSON.AnyType.swift | 86 --- Sources/BSONABI/BSON.AnyValue.swift | 504 -------------- Sources/BSONABI/BSON.Decoder.swift | 8 - Sources/BSONABI/BSON.Encoder.swift | 16 - Sources/BSONABI/BSON.TypeError.swift | 24 - Sources/BSONABI/BSON.TypecastError.swift | 24 - Sources/BSONABI/BSON.swift | 5 - Sources/BSONABI/BSONRepresentable.swift | 9 - .../BSONABI/Fields/BSON.FieldEncoder.swift | 161 ----- Sources/BSONABI/Fields/BSON.Key.swift | 61 -- Sources/BSONABI/IO/BSON.BufferFrame.swift | 12 - Sources/BSONABI/IO/BSON.BufferFrameType.swift | 37 - .../BSONABI/IO/BSON.BufferTraversable.swift | 32 - Sources/BSONABI/IO/BSON.HeaderError.swift | 26 - Sources/BSONABI/IO/BSON.Input.swift | 286 -------- .../IO/BSON.InputError.Expectation.swift | 29 - Sources/BSONABI/IO/BSON.InputError.swift | 31 - Sources/BSONABI/IO/BSON.Output.swift | 307 --------- Sources/BSONABI/IO/BSON.OutputStream.swift | 64 -- .../Primitives/BSON.BooleanSubtypeError.swift | 24 - .../BSONABI/Primitives/BSON.Decimal128.swift | 29 - .../BSONABI/Primitives/BSON.Document.swift | 185 ----- .../BSONABI/Primitives/BSON.Identifier.swift | 225 ------- .../BSON.IntegerOverflowError.swift | 33 - Sources/BSONABI/Primitives/BSON.List.swift | 153 ----- Sources/BSONABI/Primitives/BSON.Max.swift | 14 - .../BSONABI/Primitives/BSON.Millisecond.swift | 18 - Sources/BSONABI/Primitives/BSON.Min.swift | 14 - Sources/BSONABI/Primitives/BSON.Null.swift | 11 - .../Primitives/BSON.Regex.OptionError.swift | 24 - .../Primitives/BSON.Regex.Options.swift | 124 ---- Sources/BSONABI/Primitives/BSON.Regex.swift | 34 - .../BSONABI/Primitives/BSON.Timestamp.swift | 41 -- Sources/BSONABI/README.md | 63 -- Sources/BSONABI/Views/BSON.BinaryFrame.swift | 30 - .../BSONABI/Views/BSON.BinarySubtype.swift | 61 -- .../Views/BSON.BinarySubtypeError.swift | 24 - Sources/BSONABI/Views/BSON.BinaryView.swift | 96 --- .../BSON.BinaryViewError.Expectation.swift | 25 - .../BSONABI/Views/BSON.BinaryViewError.swift | 25 - .../BSONABI/Views/BSON.DocumentFrame.swift | 32 - Sources/BSONABI/Views/BSON.UTF8Frame.swift | 29 - Sources/BSONABI/Views/BSON.UTF8View.swift | 153 ----- Sources/BSONDecoding/Array (ext).swift | 17 - Sources/BSONDecoding/BSON.FieldDecoder.swift | 36 - .../BSONDecoding/BSON.OptionalDecoder.swift | 77 --- .../BSONDecoding/BSON.TraceableDecoder.swift | 44 -- .../Decodability/BSONArrayDecodable.swift | 17 - .../Decodability/BSONBinaryDecodable.swift | 18 - .../Decodability/BSONDecodable.swift | 53 -- .../Decodability/BSONDocumentDecodable.swift | 22 - .../Decodability/BSONListDecodable.swift | 22 - .../Decodability/BSONStringDecodable.swift | 44 -- .../Decoding/BSON.BinaryArray.swift | 53 -- .../Decoding/BSON.BinaryDecoder.swift | 36 - .../Decoding/BSON.BinarySubtype (ext).swift | 13 - .../Decoding/BSON.BinaryTypecastError.swift | 30 - .../Decoding/BSON.BinaryView (ext).swift | 8 - .../Decoding/BSON.DecodingError.swift | 46 -- .../Decoding/BSON.Document (ext).swift | 21 - .../BSON.DocumentDecoder.Iterator.swift | 23 - .../Decoding/BSON.DocumentDecoder.swift | 126 ---- .../Decoding/BSON.DocumentKeyError.swift | 40 -- .../Decoding/BSON.List (ext).swift | 23 - .../Decoding/BSON.ListDecoder.swift | 77 --- .../BSONDecoding/Decoding/BSON.Shape.swift | 63 -- .../Decoding/BSON.ShapeError.Criteria.swift | 10 - .../Decoding/BSON.ShapeError.swift | 38 -- .../Decoding/BSON.SingleKeyError.swift | 34 - .../Decoding/BSON.UTF8View (ext).swift | 8 - .../Decoding/BSON.ValueError.swift | 28 - Sources/BSONDecoding/Dictionary (ext).swift | 25 - .../Extensions/BSON.Decimal128 (ext).swift | 8 - .../Extensions/BSON.Identifier (ext).swift | 8 - .../Extensions/BSON.Key (ext).swift | 3 - .../Extensions/BSON.Max (ext).swift | 8 - .../Extensions/BSON.Min (ext).swift | 8 - .../Extensions/BSON.Null (ext).swift | 8 - .../Extensions/BSON.Regex (ext).swift | 13 - .../Extensions/BSON.Timestamp (ext).swift | 21 - .../BSONDecoding/Extensions/Bool (ext).swift | 8 - .../Extensions/Character (ext).swift | 24 - .../Extensions/Double (ext).swift | 3 - .../BSONDecoding/Extensions/Float (ext).swift | 3 - .../Extensions/Float80 (ext).swift | 5 - .../BSONDecoding/Extensions/Int (ext).swift | 3 - .../BSONDecoding/Extensions/Int16 (ext).swift | 3 - .../BSONDecoding/Extensions/Int32 (ext).swift | 3 - .../BSONDecoding/Extensions/Int64 (ext).swift | 3 - .../BSONDecoding/Extensions/Int8 (ext).swift | 3 - .../Extensions/Milliseconds (ext).swift | 5 - .../Extensions/Minutes (ext).swift | 5 - .../BSONDecoding/Extensions/Never (ext).swift | 9 - .../Extensions/Seconds (ext).swift | 5 - .../BSONDecoding/Extensions/Set (ext).swift | 17 - .../Extensions/String (ext).swift | 15 - .../BSONDecoding/Extensions/UInt (ext).swift | 3 - .../Extensions/UInt16 (ext).swift | 3 - .../Extensions/UInt32 (ext).swift | 3 - .../Extensions/UInt64 (ext).swift | 3 - .../BSONDecoding/Extensions/UInt8 (ext).swift | 3 - .../Extensions/Unicode.Scalar (ext).swift | 5 - .../Extensions/UnixMillisecond (ext).swift | 10 - Sources/BSONDecoding/Optional (ext).swift | 15 - Sources/BSONDecoding/README.md | 1 - Sources/BSONDecoding/exports.swift | 1 - Sources/BSONDecodingTests/DecodeBinary.swift | 19 - .../BSONDecodingTests/DecodeDocument.swift | 111 --- Sources/BSONDecodingTests/DecodeList.swift | 126 ---- Sources/BSONDecodingTests/DecodeNumeric.swift | 57 -- Sources/BSONDecodingTests/DecodeString.swift | 74 -- Sources/BSONDecodingTests/DecodeVoid.swift | 42 -- Sources/BSONEncoding/Array (ext).swift | 3 - Sources/BSONEncoding/Dictionary (ext).swift | 11 - .../Encodability/BSONArrayEncodable.swift | 22 - .../Encodability/BSONBinaryEncodable.swift | 18 - .../Encodability/BSONDocumentEncodable.swift | 28 - .../Encodability/BSONEncodable.swift | 72 -- .../Encodability/BSONListEncodable.swift | 43 -- .../Encodability/BSONStringEncodable.swift | 36 - .../Encoding/BSON.BinaryEncoder.swift | 79 --- .../Encoding/BSON.Document (ext).swift | 86 --- .../Encoding/BSON.DocumentEncoder.swift | 58 -- .../Encoding/BSON.FieldEncoder (ext).swift | 17 - .../Encoding/BSON.List (ext).swift | 30 - .../Encoding/BSON.ListEncoder.Index.swift | 13 - .../Encoding/BSON.ListEncoder.swift | 79 --- .../Extensions/BSON.AnyType (ext).swift | 9 - .../Extensions/BSON.BinaryView (ext).swift | 28 - .../Extensions/BSON.Decimal128 (ext).swift | 8 - .../Extensions/BSON.Identifier (ext).swift | 8 - .../Extensions/BSON.Key (ext).swift | 3 - .../Extensions/BSON.Max (ext).swift | 8 - .../Extensions/BSON.Min (ext).swift | 8 - .../Extensions/BSON.Null (ext).swift | 8 - .../Extensions/BSON.Regex (ext).swift | 9 - .../Extensions/BSON.Timestamp (ext).swift | 9 - .../Extensions/BSON.UTF8View (ext).swift | 9 - .../BSONEncoding/Extensions/Bool (ext).swift | 8 - .../Extensions/Character (ext).swift | 8 - .../Extensions/Double (ext).swift | 9 - .../BSONEncoding/Extensions/Int (ext).swift | 17 - .../BSONEncoding/Extensions/Int32 (ext).swift | 9 - .../BSONEncoding/Extensions/Int64 (ext).swift | 11 - .../Extensions/Milliseconds (ext).swift | 5 - .../Extensions/Minutes (ext).swift | 5 - .../BSONEncoding/Extensions/Never (ext).swift | 8 - .../Extensions/Seconds (ext).swift | 5 - .../Extensions/StaticString (ext).swift | 9 - .../Extensions/String (ext).swift | 9 - .../Extensions/Substring (ext).swift | 9 - .../Extensions/Unicode.Scalar (ext).swift | 8 - .../Extensions/UnixMillisecond (ext).swift | 10 - .../LazyDropWhileSequence (ext).swift | 3 - .../LazyFilterSequence (ext).swift | 3 - .../BSONEncoding/LazyMapSequence (ext).swift | 3 - .../LazyPrefixWhileSequence (ext).swift | 3 - Sources/BSONEncoding/Optional (ext).swift | 35 - Sources/BSONEncoding/README.md | 1 - Sources/BSONEncoding/exports.swift | 1 - .../Fields/Main.FieldDuplication.swift | 29 - .../Fields/Main.FieldElision.swift | 52 -- .../Inference/Main.LiteralInference.swift | 121 ---- .../Inference/Main.TypeInference.swift | 57 -- .../Main.EncodeDocument.swift | 36 - .../BSONEncodingTests/Main.EncodeList.swift | 34 - .../BSONEncodingTests/Main.EncodeString.swift | 29 - Sources/BSONEncodingTests/Main.swift | 19 - .../BSONEncodingTests/TestBattery (ext).swift | 32 - .../Main.EnumeratedCodingKeys.swift | 80 --- Sources/BSONIntegrationTests/Main.swift | 8 - Sources/BSONLegacy/BSON.AnyValue (ext).swift | 32 - .../BSONLegacy/BSON.KeyedDecoder.Super.swift | 9 - Sources/BSONLegacy/BSON.KeyedDecoder.swift | 183 ----- .../BSONLegacy/BSON.SingleValueDecoder.swift | 156 ----- .../BSON.UnkeyedDecoder.Index.swift | 31 - Sources/BSONLegacy/BSON.UnkeyedDecoder.swift | 190 ------ Sources/BSONLegacy/DecodingError (ext).swift | 14 - .../BSONReflection/BSON.AnyValue (ext).swift | 164 ----- .../BSONReflection/BSON.Document (ext).swift | 81 --- Sources/BSONReflection/BSON.Indent.swift | 57 -- Sources/BSONReflection/BSON.List (ext).swift | 57 -- Sources/BSONReflection/lexemes.swift | 1 - .../BSONReflectionTests/Main.Documents.swift | 256 ------- Sources/BSONReflectionTests/Main.swift | 8 - Sources/BSONTesting/TestGroup (ext).swift | 29 - Sources/BSONTesting/exports.swift | 1 - Sources/BSONTests/Main.InvalidBSON.swift | 328 --------- Sources/BSONTests/Main.ValidBSON.swift | 635 ------------------ Sources/BSONTests/Main.swift | 8 - .../OrderedDictionary (ext).swift | 38 -- Sources/BSON_UUID/UUID (ext).swift | 24 - Sources/UUID/UUID.swift | 140 ---- 202 files changed, 34 insertions(+), 9229 deletions(-) delete mode 100644 Benchmarks/.benchmarkBaselines/BSONEncodingBenchmarks/default/results.json delete mode 100644 Benchmarks/Benchmarks/BSONEncoding/Main.swift delete mode 100644 Benchmarks/Benchmarks/BSONEncoding/Scheme.swift delete mode 100644 Benchmarks/Package.resolved delete mode 100644 Benchmarks/Package.swift delete mode 100644 Sources/BSON/README.md delete mode 100644 Sources/BSON/exports.swift delete mode 100644 Sources/BSONABI/BSON.AnyType.swift delete mode 100644 Sources/BSONABI/BSON.AnyValue.swift delete mode 100644 Sources/BSONABI/BSON.Decoder.swift delete mode 100644 Sources/BSONABI/BSON.Encoder.swift delete mode 100644 Sources/BSONABI/BSON.TypeError.swift delete mode 100644 Sources/BSONABI/BSON.TypecastError.swift delete mode 100644 Sources/BSONABI/BSON.swift delete mode 100644 Sources/BSONABI/BSONRepresentable.swift delete mode 100644 Sources/BSONABI/Fields/BSON.FieldEncoder.swift delete mode 100644 Sources/BSONABI/Fields/BSON.Key.swift delete mode 100644 Sources/BSONABI/IO/BSON.BufferFrame.swift delete mode 100644 Sources/BSONABI/IO/BSON.BufferFrameType.swift delete mode 100644 Sources/BSONABI/IO/BSON.BufferTraversable.swift delete mode 100644 Sources/BSONABI/IO/BSON.HeaderError.swift delete mode 100644 Sources/BSONABI/IO/BSON.Input.swift delete mode 100644 Sources/BSONABI/IO/BSON.InputError.Expectation.swift delete mode 100644 Sources/BSONABI/IO/BSON.InputError.swift delete mode 100644 Sources/BSONABI/IO/BSON.Output.swift delete mode 100644 Sources/BSONABI/IO/BSON.OutputStream.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.BooleanSubtypeError.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Decimal128.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Document.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Identifier.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.IntegerOverflowError.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.List.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Max.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Millisecond.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Min.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Null.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Regex.OptionError.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Regex.Options.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Regex.swift delete mode 100644 Sources/BSONABI/Primitives/BSON.Timestamp.swift delete mode 100644 Sources/BSONABI/README.md delete mode 100644 Sources/BSONABI/Views/BSON.BinaryFrame.swift delete mode 100644 Sources/BSONABI/Views/BSON.BinarySubtype.swift delete mode 100644 Sources/BSONABI/Views/BSON.BinarySubtypeError.swift delete mode 100644 Sources/BSONABI/Views/BSON.BinaryView.swift delete mode 100644 Sources/BSONABI/Views/BSON.BinaryViewError.Expectation.swift delete mode 100644 Sources/BSONABI/Views/BSON.BinaryViewError.swift delete mode 100644 Sources/BSONABI/Views/BSON.DocumentFrame.swift delete mode 100644 Sources/BSONABI/Views/BSON.UTF8Frame.swift delete mode 100644 Sources/BSONABI/Views/BSON.UTF8View.swift delete mode 100644 Sources/BSONDecoding/Array (ext).swift delete mode 100644 Sources/BSONDecoding/BSON.FieldDecoder.swift delete mode 100644 Sources/BSONDecoding/BSON.OptionalDecoder.swift delete mode 100644 Sources/BSONDecoding/BSON.TraceableDecoder.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONArrayDecodable.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONBinaryDecodable.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONDecodable.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONDocumentDecodable.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONListDecodable.swift delete mode 100644 Sources/BSONDecoding/Decodability/BSONStringDecodable.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.BinaryArray.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.BinaryDecoder.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.BinarySubtype (ext).swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.BinaryTypecastError.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.BinaryView (ext).swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.DecodingError.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.Document (ext).swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.Iterator.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.DocumentKeyError.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.List (ext).swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.ListDecoder.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.Shape.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.ShapeError.Criteria.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.ShapeError.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.SingleKeyError.swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.UTF8View (ext).swift delete mode 100644 Sources/BSONDecoding/Decoding/BSON.ValueError.swift delete mode 100644 Sources/BSONDecoding/Dictionary (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Decimal128 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Identifier (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Key (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Max (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Min (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Null (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Regex (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/BSON.Timestamp (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Bool (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Character (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Double (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Float (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Float80 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Int (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Int16 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Int32 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Int64 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Int8 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Milliseconds (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Minutes (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Never (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Seconds (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Set (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/String (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UInt (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UInt16 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UInt32 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UInt64 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UInt8 (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/Unicode.Scalar (ext).swift delete mode 100644 Sources/BSONDecoding/Extensions/UnixMillisecond (ext).swift delete mode 100644 Sources/BSONDecoding/Optional (ext).swift delete mode 100644 Sources/BSONDecoding/README.md delete mode 100644 Sources/BSONDecoding/exports.swift delete mode 100644 Sources/BSONDecodingTests/DecodeBinary.swift delete mode 100644 Sources/BSONDecodingTests/DecodeDocument.swift delete mode 100644 Sources/BSONDecodingTests/DecodeList.swift delete mode 100644 Sources/BSONDecodingTests/DecodeNumeric.swift delete mode 100644 Sources/BSONDecodingTests/DecodeString.swift delete mode 100644 Sources/BSONDecodingTests/DecodeVoid.swift delete mode 100644 Sources/BSONEncoding/Array (ext).swift delete mode 100644 Sources/BSONEncoding/Dictionary (ext).swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONArrayEncodable.swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONBinaryEncodable.swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONDocumentEncodable.swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONEncodable.swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONListEncodable.swift delete mode 100644 Sources/BSONEncoding/Encodability/BSONStringEncodable.swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.BinaryEncoder.swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.Document (ext).swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.DocumentEncoder.swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.FieldEncoder (ext).swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.List (ext).swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.ListEncoder.Index.swift delete mode 100644 Sources/BSONEncoding/Encoding/BSON.ListEncoder.swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.AnyType (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.BinaryView (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Decimal128 (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Identifier (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Key (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Max (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Min (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Null (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Regex (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.Timestamp (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/BSON.UTF8View (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Bool (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Character (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Double (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Int (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Int32 (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Int64 (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Milliseconds (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Minutes (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Never (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Seconds (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/StaticString (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/String (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Substring (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/Unicode.Scalar (ext).swift delete mode 100644 Sources/BSONEncoding/Extensions/UnixMillisecond (ext).swift delete mode 100644 Sources/BSONEncoding/LazyDropWhileSequence (ext).swift delete mode 100644 Sources/BSONEncoding/LazyFilterSequence (ext).swift delete mode 100644 Sources/BSONEncoding/LazyMapSequence (ext).swift delete mode 100644 Sources/BSONEncoding/LazyPrefixWhileSequence (ext).swift delete mode 100644 Sources/BSONEncoding/Optional (ext).swift delete mode 100644 Sources/BSONEncoding/README.md delete mode 100644 Sources/BSONEncoding/exports.swift delete mode 100644 Sources/BSONEncodingTests/Fields/Main.FieldDuplication.swift delete mode 100644 Sources/BSONEncodingTests/Fields/Main.FieldElision.swift delete mode 100644 Sources/BSONEncodingTests/Inference/Main.LiteralInference.swift delete mode 100644 Sources/BSONEncodingTests/Inference/Main.TypeInference.swift delete mode 100644 Sources/BSONEncodingTests/Main.EncodeDocument.swift delete mode 100644 Sources/BSONEncodingTests/Main.EncodeList.swift delete mode 100644 Sources/BSONEncodingTests/Main.EncodeString.swift delete mode 100644 Sources/BSONEncodingTests/Main.swift delete mode 100644 Sources/BSONEncodingTests/TestBattery (ext).swift delete mode 100644 Sources/BSONIntegrationTests/Main.EnumeratedCodingKeys.swift delete mode 100644 Sources/BSONIntegrationTests/Main.swift delete mode 100644 Sources/BSONLegacy/BSON.AnyValue (ext).swift delete mode 100644 Sources/BSONLegacy/BSON.KeyedDecoder.Super.swift delete mode 100644 Sources/BSONLegacy/BSON.KeyedDecoder.swift delete mode 100644 Sources/BSONLegacy/BSON.SingleValueDecoder.swift delete mode 100644 Sources/BSONLegacy/BSON.UnkeyedDecoder.Index.swift delete mode 100644 Sources/BSONLegacy/BSON.UnkeyedDecoder.swift delete mode 100644 Sources/BSONLegacy/DecodingError (ext).swift delete mode 100644 Sources/BSONReflection/BSON.AnyValue (ext).swift delete mode 100644 Sources/BSONReflection/BSON.Document (ext).swift delete mode 100644 Sources/BSONReflection/BSON.Indent.swift delete mode 100644 Sources/BSONReflection/BSON.List (ext).swift delete mode 100644 Sources/BSONReflection/lexemes.swift delete mode 100644 Sources/BSONReflectionTests/Main.Documents.swift delete mode 100644 Sources/BSONReflectionTests/Main.swift delete mode 100644 Sources/BSONTesting/TestGroup (ext).swift delete mode 100644 Sources/BSONTesting/exports.swift delete mode 100644 Sources/BSONTests/Main.InvalidBSON.swift delete mode 100644 Sources/BSONTests/Main.ValidBSON.swift delete mode 100644 Sources/BSONTests/Main.swift delete mode 100644 Sources/BSON_OrderedCollections/OrderedDictionary (ext).swift delete mode 100644 Sources/BSON_UUID/UUID (ext).swift delete mode 100644 Sources/UUID/UUID.swift diff --git a/Benchmarks/.benchmarkBaselines/BSONEncodingBenchmarks/default/results.json b/Benchmarks/.benchmarkBaselines/BSONEncodingBenchmarks/default/results.json deleted file mode 100644 index 5fd55b6e..00000000 --- a/Benchmarks/.benchmarkBaselines/BSONEncodingBenchmarks/default/results.json +++ /dev/null @@ -1 +0,0 @@ -{"results":[{"target":"BSONEncodingBenchmarks","name":"dates"},[{"metric":{"cpuUser":{}},"timeUnits":1000,"percentiles":[{"p0":{}},450,{"p75":{}},490,{"p25":{}},470,{"p90":{}},510,{"p99":{}},510,{"p100":{}},510,{"p50":{}},480],"measurements":20,"warmupIterations":3},{"metric":{"cpuTotal":{}},"timeUnits":1000,"percentiles":[{"p100":{}},560,{"p0":{}},510,{"p75":{}},530,{"p99":{}},560,{"p25":{}},510,{"p50":{}},520,{"p90":{}},540],"measurements":20,"warmupIterations":3},{"metric":{"throughput":{}},"timeUnits":1000000000,"percentiles":[{"p90":{}},2,{"p75":{}},2,{"p100":{}},2,{"p25":{}},2,{"p0":{}},2,{"p50":{}},2,{"p99":{}},2],"measurements":20,"warmupIterations":3},{"metric":{"mallocCountSmall":{}},"timeUnits":1000000,"percentiles":[{"p50":{}},5818,{"p0":{}},5818,{"p25":{}},5818,{"p100":{}},5818,{"p90":{}},5818,{"p75":{}},5818,{"p99":{}},5818],"measurements":20,"warmupIterations":3},{"timeUnits":1000000000,"warmupIterations":3,"metric":{"mallocCountLarge":{}},"percentiles":[{"p50":{}},5,{"p25":{}},5,{"p100":{}},5,{"p90":{}},5,{"p75":{}},5,{"p0":{}},5,{"p99":{}},5],"measurements":20}]],"machine":{"memory":30,"processors":12,"processorType":"x86_64","kernelVersion":"#59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022","hostname":"2fe6764bbf1e"}} \ No newline at end of file diff --git a/Benchmarks/Benchmarks/BSONEncoding/Main.swift b/Benchmarks/Benchmarks/BSONEncoding/Main.swift deleted file mode 100644 index 5987b086..00000000 --- a/Benchmarks/Benchmarks/BSONEncoding/Main.swift +++ /dev/null @@ -1,47 +0,0 @@ -import BenchmarkSupport -import BSONEncoding - -@main -extension BenchmarkRunner -{ -} - -@_dynamicReplacement(for: registerBenchmarks) -func benchmarks() -{ - // generate dates - var dates:[Date] = [] - var index:Int = 4 - for year:Date.Year in 1492 ... 2022 - { - for month:Date.Month in Date.Month.allCases - { - for day:Int in 1 ... year.days(in: month) - { - let date:Date = .init(year: year, month: month, day: day, - weekday: Date.Weekday.allCases[index % 7]) - dates.append(date) - index += 1 - } - } - } - print("generated \(dates.count) dates") - Benchmark.init("dates", configuration: .init( - metrics: BenchmarkMetric.all, - timeUnits: .microseconds, - desiredDuration: .seconds(10))) - { - benchmark in - - for _:Int in 0 ..< 5 - { - blackHole(encode(dates: dates)) - } - } -} - -@inline(never) -func encode(dates:[Date]) -> [BSON.Document] -{ - dates.map { .init(with: $0.encode(to:)) } -} diff --git a/Benchmarks/Benchmarks/BSONEncoding/Scheme.swift b/Benchmarks/Benchmarks/BSONEncoding/Scheme.swift deleted file mode 100644 index 880c67b2..00000000 --- a/Benchmarks/Benchmarks/BSONEncoding/Scheme.swift +++ /dev/null @@ -1,146 +0,0 @@ -import BSONEncoding - -extension Date -{ - struct Year:RawRepresentable - { - let rawValue:Int32 - - init(rawValue:Int32) - { - self.rawValue = rawValue - } - } -} -extension Date.Year -{ - var leap:Int - { - self.rawValue % 4 != 0 ? 0 : - self.rawValue % 100 != 0 ? 1 : - self.rawValue % 400 != 0 ? 0 : 1 - } - - func days(in month:Date.Month) -> Int - { - switch month - { - case .january: return 31 - case .february: return 28 + self.leap - case .march: return 31 - case .april: return 30 - case .may: return 31 - case .june: return 30 - case .july: return 31 - case .august: return 31 - case .september: return 30 - case .october: return 31 - case .november: return 30 - case .december: return 31 - } - } -} -extension Date.Year:Strideable -{ - func advanced(by step:Int32) -> Self - { - .init(rawValue: self.rawValue + step) - } - func distance(to end:Self) -> Int32 - { - end.rawValue - self.rawValue - } -} -extension Date.Year:ExpressibleByIntegerLiteral -{ - init(integerLiteral:Int32) - { - self.init(rawValue: integerLiteral) - } -} -extension Date.Year:CustomStringConvertible -{ - var description:String - { - self.rawValue.description - } -} -extension Date.Year:BSONEncodable -{ -} - -extension Date -{ - enum Month:Int32, CaseIterable - { - case january = 1 - case february - case march - case april - case may - case june - case july - case august - case september - case october - case november - case december - } -} -extension Date.Month:BSONEncodable -{ -} - -extension Date -{ - enum Weekday:String, CaseIterable - { - case monday - case tuesday - case wednesday - case thursday - case friday - case saturday - case sunday - } -} -extension Date.Weekday:BSONEncodable -{ -} - -struct Date -{ - let year:Year - let month:Month - let day:Int - let weekday:Weekday - var comment:String - - init(year:Year, month:Month, day:Int, weekday:Weekday) - { - self.year = year - self.month = month - self.day = day - self.weekday = weekday - self.comment = "" - self.comment = self.description - } -} -extension Date:CustomStringConvertible -{ - var description:String - { - "\(self.weekday) \(self.month) \(self.day), \(self.year)" - } -} -extension Date:BSONDocumentEncodable -{ - func encode(to bson:inout BSON.DocumentEncoder) - { - bson["year"] = self.year - bson["month"] = self.month - bson["day"] = self.day - bson["weekday"] = self.weekday - bson["comment"] = self.comment - } -} diff --git a/Benchmarks/Package.resolved b/Benchmarks/Package.resolved deleted file mode 100644 index da62c520..00000000 --- a/Benchmarks/Package.resolved +++ /dev/null @@ -1,140 +0,0 @@ -{ - "pins" : [ - { - "identity" : "package-benchmark", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ordo-one/package-benchmark", - "state" : { - "revision" : "81bd87b4eca4c1fff0275fa55fd52b1faf3814d9", - "version" : "0.8.0" - } - }, - { - "identity" : "package-datetime", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ordo-one/package-datetime", - "state" : { - "revision" : "9c1e16bfe7683e787161f866ff8b5cbc88089cb4", - "version" : "0.0.6" - } - }, - { - "identity" : "package-histogram", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ordo-one/package-histogram", - "state" : { - "revision" : "604410b21ded1ebdf06ad98100f448c68e80f5a1", - "version" : "0.1.1" - } - }, - { - "identity" : "package-jemalloc", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ordo-one/package-jemalloc", - "state" : { - "revision" : "e8a5db026963f5bfeac842d9d3f2cc8cde323b49", - "version" : "1.0.0" - } - }, - { - "identity" : "swift-argument-parser", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser", - "state" : { - "revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d", - "version" : "1.2.0" - } - }, - { - "identity" : "swift-atomics", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-atomics.git", - "state" : { - "revision" : "cd142fd2f64be2100422d658e7411e39489da985", - "version" : "1.2.0" - } - }, - { - "identity" : "swift-collections", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-collections.git", - "state" : { - "revision" : "a902f1823a7ff3c9ab2fba0f992396b948eda307", - "version" : "1.0.5" - } - }, - { - "identity" : "swift-extras-json", - "kind" : "remoteSourceControl", - "location" : "https://github.com/swift-extras/swift-extras-json", - "state" : { - "revision" : "122b9454ef01bf89a4c190b8fd3717ddd0a2fbd0", - "version" : "0.6.0" - } - }, - { - "identity" : "swift-grammar", - "kind" : "remoteSourceControl", - "location" : "https://github.com/tayloraswift/swift-grammar", - "state" : { - "revision" : "3ed94966b1fd8145c2624a5955a9f0d17663280b", - "version" : "0.3.2" - } - }, - { - "identity" : "swift-hash", - "kind" : "remoteSourceControl", - "location" : "https://github.com/tayloraswift/swift-hash", - "state" : { - "revision" : "c7ba0cde5eb63042c2196b02b65a770101c1ac11", - "version" : "0.5.0" - } - }, - { - "identity" : "swift-nio", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio.git", - "state" : { - "revision" : "702cd7c56d5d44eeba73fdf83918339b26dc855c", - "version" : "2.62.0" - } - }, - { - "identity" : "swift-nio-ssl", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-ssl.git", - "state" : { - "revision" : "320bd978cceb8e88c125dcbb774943a92f6286e9", - "version" : "2.25.0" - } - }, - { - "identity" : "swift-numerics", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-numerics", - "state" : { - "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", - "version" : "1.0.2" - } - }, - { - "identity" : "swift-system", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-system", - "state" : { - "revision" : "025bcb1165deab2e20d4eaba79967ce73013f496", - "version" : "1.2.1" - } - }, - { - "identity" : "texttable", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ordo-one/TextTable", - "state" : { - "revision" : "a27a07300cf4ae322e0079ca0a475c5583dd575f", - "version" : "0.0.2" - } - } - ], - "version" : 2 -} diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift deleted file mode 100644 index 669bab08..00000000 --- a/Benchmarks/Package.swift +++ /dev/null @@ -1,24 +0,0 @@ -// swift-tools-version:5.8 -import PackageDescription - -let package:Package = .init(name: "swift-mongodb-benchmarks", - products: - [ - ], - dependencies: - [ - .package(url: "https://github.com/ordo-one/package-benchmark", - .upToNextMajor(from: "0.8.0")), - .package(path: ".."), - ], - targets: - [ - .executableTarget(name: "BSONEncodingBenchmarks", - dependencies: - [ - .product(name: "BenchmarkSupport", package: "package-benchmark"), - .product(name: "BSONEncoding", package: "swift-mongodb"), - ], - path: "Benchmarks/BSONEncoding"), - ] -) diff --git a/Package.resolved b/Package.resolved index 9183d98e..9e16e3ce 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "f3f9fc391509642da9593d2b621fe1a85a1b66c4e7197e28b38bf613cc7baabf", + "originHash" : "d103f65c5cac0a89a90d4ceb4944e9e2408d92b116eaf3ae3884f93cb3751e03", "pins" : [ { "identity" : "swift-atomics", @@ -10,13 +10,22 @@ "version" : "1.2.0" } }, + { + "identity" : "swift-bson", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tayloraswift/swift-bson", + "state" : { + "revision" : "717200e9505333dfc3d9045d6ddeb20981765285", + "version" : "0.1.0" + } + }, { "identity" : "swift-collections", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d", - "version" : "1.1.2" + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" } }, { @@ -24,8 +33,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/tayloraswift/swift-grammar", "state" : { - "revision" : "642d5957896f06b03e35c48fc439488367d3fd21", - "version" : "0.4.0" + "revision" : "4b47a153732e0b094ef7dd95d891b37b7ae37a69", + "version" : "0.4.1" } }, { @@ -33,8 +42,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/tayloraswift/swift-hash", "state" : { - "revision" : "7a3fbb75ec4c88421796faaf0b47f16ffc21b348", - "version" : "0.6.2" + "revision" : "5550cee96edd9ecfd7e600df739e5bf4bae022a4", + "version" : "0.7.0" } }, { diff --git a/Package.swift b/Package.swift index 5dcbbaf1..a798e6cd 100644 --- a/Package.swift +++ b/Package.swift @@ -6,107 +6,34 @@ let package:Package = .init(name: "swift-mongodb", .macOS(.v15), ], products: [ - .library(name: "BSON", targets: ["BSON"]), - .library(name: "BSONLegacy", targets: ["BSONLegacy"]), - .library(name: "BSONReflection", targets: ["BSONReflection"]), - .library(name: "BSONTesting", targets: ["BSONTesting"]), - .library(name: "BSONABI", targets: ["BSONABI"]), - - .library(name: "BSON_OrderedCollections", targets: ["BSON_OrderedCollections"]), - .library(name: "BSON_UUID", targets: ["BSON_UUID"]), - .library(name: "MongoDB", targets: ["MongoDB"]), .library(name: "MongoQL", targets: ["MongoQL"]), .library(name: "MongoTesting", targets: ["MongoTesting"]), .library(name: "SCRAM", targets: ["SCRAM"]), .library(name: "UnixTime_Atomics", targets: ["UnixTime_Atomics"]), - .library(name: "UUID", targets: ["UUID"]), ], dependencies: [ + .package(url: "https://github.com/tayloraswift/swift-bson", .upToNextMinor( + from: "0.1.0")), .package(url: "https://github.com/tayloraswift/swift-grammar", .upToNextMinor( from: "0.4.0")), .package(url: "https://github.com/tayloraswift/swift-hash", .upToNextMinor( - from: "0.6.0")), + from: "0.7.0")), .package(url: "https://github.com/tayloraswift/swift-unixtime", .upToNextMinor( from: "0.1.5")), - .package(url: "https://github.com/apple/swift-atomics.git", .upToNextMinor( + .package(url: "https://github.com/apple/swift-atomics", .upToNextMinor( from: "1.2.0")), - .package(url: "https://github.com/apple/swift-collections.git", .upToNextMinor( + .package(url: "https://github.com/apple/swift-collections", .upToNextMinor( from: "1.1.0")), - .package(url: "https://github.com/apple/swift-nio.git", from: "2.75.0"), - .package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.28.0"), + .package(url: "https://github.com/apple/swift-nio", + from: "2.75.0"), + .package(url: "https://github.com/apple/swift-nio-ssl", + from: "2.28.0"), ], targets: [ - .target(name: "UUID", - dependencies: [ - .product(name: "Base16", package: "swift-hash"), - ]), - - .target(name: "BSON", - dependencies: [ - .target(name: "BSONDecoding"), - .target(name: "BSONEncoding"), - ], - exclude: [ - "README.md", - ]), - - .target(name: "BSONABI", - dependencies: [ - .product(name: "UnixTime", package: "swift-unixtime"), - ], - exclude: [ - "README.md", - ]), - - .target(name: "BSONDecoding", - dependencies: [ - .target(name: "BSONABI"), - .product(name: "TraceableErrors", package: "swift-grammar"), - ], - exclude: [ - "README.md", - ]), - - .target(name: "BSONEncoding", - dependencies: [ - .target(name: "BSONABI"), - ], - exclude: [ - "README.md", - ]), - - .target(name: "BSONLegacy", - dependencies: [ - .target(name: "BSON"), - ]), - - .target(name: "BSONReflection", - dependencies: [ - .target(name: "BSON"), - ]), - - .target(name: "BSONTesting", - dependencies: [ - .target(name: "BSON"), - .product(name: "Testing_", package: "swift-grammar"), - ]), - - .target(name: "BSON_UUID", - dependencies: [ - .target(name: "BSON"), - .target(name: "UUID"), - ]), - - .target(name: "BSON_OrderedCollections", - dependencies: [ - .target(name: "BSON"), - .product(name: "OrderedCollections", package: "swift-collections"), - ]), - .target(name: "OnlineCDF"), .target(name: "SCRAM", @@ -120,8 +47,8 @@ let package:Package = .init(name: "swift-mongodb", .target(name: "MongoABI", dependencies: [ - .target(name: "BSON"), .target(name: "Mongo"), + .product(name: "BSON", package: "swift-bson"), ]), .target(name: "MongoBuiltins", @@ -131,10 +58,9 @@ let package:Package = .init(name: "swift-mongodb", .target(name: "MongoClusters", dependencies: [ - .target(name: "BSON"), .target(name: "Mongo"), + .product(name: "BSON", package: "swift-bson"), .product(name: "TraceableErrors", package: "swift-grammar"), - .product(name: "UnixTime", package: "swift-unixtime"), ]), .target(name: "MongoCommands", @@ -158,14 +84,14 @@ let package:Package = .init(name: "swift-mongodb", .target(name: "MongoDriver", dependencies: [ - .target(name: "BSON_OrderedCollections"), - .target(name: "BSON_UUID"), .target(name: "MongoCommands"), .target(name: "MongoConfiguration"), .target(name: "MongoExecutor"), .target(name: "MongoLogging"), .target(name: "SCRAM"), .target(name: "UnixTime_Atomics"), + .product(name: "BSON_OrderedCollections", package: "swift-bson"), + .product(name: "BSON_UUID", package: "swift-bson"), .product(name: "Atomics", package: "swift-atomics"), .product(name: "SHA2", package: "swift-hash"), .product(name: "NIOPosix", package: "swift-nio"), @@ -192,12 +118,12 @@ let package:Package = .init(name: "swift-mongodb", .target(name: "MongoQL", dependencies: [ - .target(name: "BSON"), - .target(name: "BSONReflection"), - .target(name: "BSON_OrderedCollections"), - .target(name: "BSON_UUID"), .target(name: "MongoBuiltins"), .target(name: "MongoCommands"), + .product(name: "BSON", package: "swift-bson"), + .product(name: "BSONReflection", package: "swift-bson"), + .product(name: "BSON_OrderedCollections", package: "swift-bson"), + .product(name: "BSON_UUID", package: "swift-bson"), ]), .target(name: "MongoTesting", @@ -209,8 +135,8 @@ let package:Package = .init(name: "swift-mongodb", // driver-level concepts. .target(name: "MongoWire", dependencies: [ - .target(name: "BSON"), .target(name: "Mongo"), + .product(name: "BSON", package: "swift-bson"), .product(name: "CRC", package: "swift-hash"), ]), @@ -220,38 +146,6 @@ let package:Package = .init(name: "swift-mongodb", .product(name: "UnixTime", package: "swift-unixtime"), ]), - .executableTarget(name: "BSONTests", - dependencies: [ - .target(name: "BSONReflection"), - .target(name: "BSON_UUID"), - .product(name: "Base16", package: "swift-hash"), - .product(name: "Testing_", package: "swift-grammar"), - ]), - - .testTarget(name: "BSONDecodingTests", - dependencies: [ - .target(name: "BSONDecoding"), - ]), - - .executableTarget(name: "BSONEncodingTests", - dependencies: [ - .target(name: "BSONEncoding"), - .product(name: "Testing_", package: "swift-grammar"), - ]), - - .executableTarget(name: "BSONIntegrationTests", - dependencies: [ - .target(name: "BSON"), - .target(name: "BSONReflection"), - .product(name: "Testing_", package: "swift-grammar"), - ]), - - .executableTarget(name: "BSONReflectionTests", - dependencies: [ - .target(name: "BSONReflection"), - .target(name: "BSONEncoding"), - .product(name: "Testing_", package: "swift-grammar"), - ]), .executableTarget(name: "OnlineCDFTests", dependencies: [ diff --git a/Sources/BSON/README.md b/Sources/BSON/README.md deleted file mode 100644 index cd2a8a29..00000000 --- a/Sources/BSON/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# ``/BSON`` - -An umbrella module providing a BSON parser, encoder, and decoder. - -## Linking the BSON libraries - -This module re-exports the ``BSONABI``, ``BSONEncoding``, and ``BSONDecoding`` modules. Importing them directly is discouraged. - -Some BSON modules (currently ``BSONLegacy``, ``BSONReflection``, and ``BSONTesting``) are considered ancillary and are not included in this umbrella module. diff --git a/Sources/BSON/exports.swift b/Sources/BSON/exports.swift deleted file mode 100644 index bf97bf35..00000000 --- a/Sources/BSON/exports.swift +++ /dev/null @@ -1,3 +0,0 @@ -@_exported import BSONABI -@_exported import BSONDecoding -@_exported import BSONEncoding diff --git a/Sources/BSONABI/BSON.AnyType.swift b/Sources/BSONABI/BSON.AnyType.swift deleted file mode 100644 index 5d251bed..00000000 --- a/Sources/BSONABI/BSON.AnyType.swift +++ /dev/null @@ -1,86 +0,0 @@ -extension BSON -{ - /// A BSON metatype. The raw value of this enumeration is the type code of the associated - /// case in BSON’s ABI. - @frozen public - enum AnyType:UInt8, Equatable, Hashable, Sendable - { - case double = 0x01 - case string = 0x02 - case document = 0x03 - case list = 0x04 - case binary = 0x05 - - case id = 0x07 - case bool = 0x08 - case millisecond = 0x09 - case null = 0x0A - case regex = 0x0B - case pointer = 0x0C - case javascript = 0x0D - - case javascriptScope = 0x0F - case int32 = 0x10 - case timestamp = 0x11 - case int64 = 0x12 - case decimal128 = 0x13 - - case min = 0xFF - case max = 0x7F - } -} -extension BSON.AnyType -{ - /// Calls ``init(rawValue:)``, but throws a ``TypeError`` instead of returning - /// nil. - @inlinable public - init(code:UInt8) throws - { - if let variant:Self = .init(rawValue: code) - { - self = variant - } - else - { - throw BSON.TypeError.init(invalid: code) - } - } - /// Converts the given type code to a variant type. This function will canonicalize - /// deprecated type codes that have an isomorphic modern equivalent, but it will - /// never change the ``pointer`` and ``javascriptScope`` types, because they do not - /// have modern equivalents. - @inlinable public - init?(rawValue:UInt8) - { - switch rawValue - { - case 0x01: self = .double - case 0x02: self = .string - case 0x03: self = .document - case 0x04: self = .list - case 0x05: self = .binary - case 0x06: self = .null - case 0x07: self = .id - case 0x08: self = .bool - case 0x09: self = .millisecond - case 0x0A: self = .null - case 0x0B: self = .regex - case 0x0C: self = .pointer - case 0x0D: self = .javascript - case 0x0E: self = .string - case 0x0F: self = .javascriptScope - case 0x10: self = .int32 - case 0x11: self = .timestamp - case 0x12: self = .int64 - case 0x13: self = .decimal128 - case 0xFF: self = .min - case 0x7F: self = .max - default: return nil - } - } -} -extension BSON.AnyType:Comparable -{ - @inlinable public - static func < (a:Self, b:Self) -> Bool { a.rawValue < b.rawValue } -} diff --git a/Sources/BSONABI/BSON.AnyValue.swift b/Sources/BSONABI/BSON.AnyValue.swift deleted file mode 100644 index efa05ec7..00000000 --- a/Sources/BSONABI/BSON.AnyValue.swift +++ /dev/null @@ -1,504 +0,0 @@ -import UnixTime - -extension BSON -{ - /// Any BSON value. - @frozen public - enum AnyValue:Equatable, Sendable - { - /// A general embedded document. - case document(BSON.Document) - /// An embedded list-document. - case list(BSON.List) - /// A binary array. - case binary(BSON.BinaryView>) - /// A boolean. - case bool(Bool) - /// An [IEEE 754-2008 128-bit - /// decimal](https://en.wikipedia.org/wiki/Decimal128_floating-point_format). - case decimal128(BSON.Decimal128) - /// A double-precision float. - case double(Double) - /// A MongoDB object reference. - case id(BSON.Identifier) - /// A 32-bit signed integer. - case int32(Int32) - /// A 64-bit signed integer. - case int64(Int64) - /// Javascript code. - /// The payload is a library type to permit efficient document traversal. - case javascript(BSON.UTF8View>) - /// A javascript scope containing code. This variant is maintained for - /// backward-compatibility with older versions of BSON and - /// should not be generated. (Prefer ``javascript(_:)``.) - case javascriptScope(BSON.Document, BSON.UTF8View>) - /// The MongoDB max-key. - case max - /// UTC milliseconds since the Unix epoch. - case millisecond(UnixMillisecond) - /// The MongoDB min-key. - case min - /// An explicit null. - case null - /// A MongoDB database pointer. This variant is maintained for - /// backward-compatibility with older versions of BSON and - /// should not be generated. (Prefer ``id(_:)``.) - case pointer(BSON.UTF8View>, BSON.Identifier) - /// A regex. - case regex(BSON.Regex) - /// A UTF-8 string, possibly containing invalid code units. - /// The payload is a library type to permit efficient document traversal. - case string(BSON.UTF8View>) - /// A 64-bit unsigned integer. - /// - /// MongoDB also uses this type internally to represent timestamps. - /// - /// > Important: - /// MongoDB replaces zero values of this type in top-level document - /// fields with the bit pattern of its “current timestamp”. This - /// behavior is not part of the BSON specification, and does not - /// affect roundtrippability of BSON documents that are not stored - /// in a Mongo database. - case timestamp(BSON.Timestamp) - } -} -extension BSON.AnyValue -{ - /// The type of this variant value. - @inlinable public - var type:BSON.AnyType - { - switch self - { - case .document: .document - case .list: .list - case .binary: .binary - case .bool: .bool - case .decimal128: .decimal128 - case .double: .double - case .id: .id - case .int32: .int32 - case .int64: .int64 - case .javascript: .javascript - case .javascriptScope: .javascriptScope - case .max: .max - case .millisecond: .millisecond - case .min: .min - case .null: .null - case .pointer: .pointer - case .regex: .regex - case .string: .string - case .timestamp: .timestamp - } - } - /// The size of this variant value when encoded. - @inlinable public - var size:Int - { - switch self - { - case .document(let document): - document.size - case .list(let list): - list.size - case .binary(let binary): - binary.size - case .bool: - 1 - case .decimal128: - 16 - case .double: - 8 - case .id: - 12 - case .int32: - 4 - case .int64: - 8 - case .javascript(let utf8): - utf8.size - case .javascriptScope(let scope, let utf8): - 4 + utf8.size + scope.size - case .max: - 0 - case .millisecond: - 8 - case .min: - 0 - case .null: - 0 - case .pointer(let database, _): - 12 + database.size - case .regex(let regex): - regex.size - case .string(let string): - string.size - case .timestamp: - 8 - } - } -} -extension BSON.AnyValue -{ - /// Promotes a nil result to a thrown ``TypecastError``. - /// - /// If `T` conforms to ``BSONDecodable``, prefer calling its throwing - /// ``BSONDecodable/init(bson:) [3CURP]`` to calling this method directly. - /// - /// > Throws: A ``TypecastError`` if the given curried method returns nil. - @inline(__always) - @inlinable public - func cast(with cast:(Self) throws -> T?) throws -> T - { - if let value:T = try cast(self) - { - return value - } - else - { - throw BSON.TypecastError.init(invalid: self.type) - } - } -} -extension BSON.AnyValue -{ - /// Attempts to load an instance of ``Bool`` from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``bool(_:)``, - /// nil otherwise. - @inlinable public - func `as`(_:Bool.Type) -> Bool? - { - switch self - { - case .bool(let bool): bool - default: nil - } - } - /// Attempts to load an instance of some ``FixedWidthInteger`` from this variant. - /// - /// - Returns: - /// An integer derived from the payload of this variant - /// if it matches one of ``int32(_:)``, ``int64(_:)``, or - /// ``timestamp(_:)``, and it can be represented exactly by `T`; - /// nil otherwise. - /// - /// The ``decimal128(_:)``, ``double(_:)``, and ``millisecond(_:)`` - /// variants will *not* match. - /// - /// This method reports failure in two ways — it returns nil on a type - /// mismatch, and it throws an ``IntegerOverflowError`` if this variant - /// was an integer, but it could not be represented exactly by `T`. - @inlinable public - func `as`(_:Integer.Type) throws -> Integer? - where Integer:FixedWidthInteger - { - switch self - { - case .int32(let int32): - if let integer:Integer = .init(exactly: int32) - { - return integer - } - else - { - throw BSON.IntegerOverflowError.int32(int32) - } - case .int64(let int64): - if let integer:Integer = .init(exactly: int64) - { - return integer - } - else - { - throw BSON.IntegerOverflowError.int64(int64) - } - case .timestamp(let timestamp): - if let integer:Integer = .init(exactly: timestamp.value) - { - return integer - } - else - { - throw BSON.IntegerOverflowError.uint64(timestamp.value) - } - default: - return nil - } - } - /// Attempts to load an instance of some ``BinaryFloatingPoint`` type from - /// this variant. - /// - /// - Returns: - /// The closest value of `T` to the payload of this - /// variant if it matches ``double(_:)``, nil otherwise. - @inlinable public - func `as`(_:Fraction.Type) -> Fraction? - where Fraction:BinaryFloatingPoint - { - switch self - { - case .double(let double): return .init(double) - default: return nil - } - } - /// Attempts to load an instance of ``Decimal128`` from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``decimal128(_:)``, - /// nil otherwise. - @inlinable public - func `as`(_:BSON.Decimal128.Type) -> BSON.Decimal128? - { - switch self - { - case .decimal128(let decimal): decimal - default: nil - } - } - /// Attempts to load an instance of ``Identifier`` from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``id(_:)`` or - /// ``pointer(_:_:)``, nil otherwise. - @inlinable public - func `as`(_:BSON.Identifier.Type) -> BSON.Identifier? - { - switch self - { - case .id(let id): - id - case .pointer(_, let id): - id - default: - nil - } - } - /// Attempts to load an instance of ``UnixMillisecond`` from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``millisecond(_:)``, - /// nil otherwise. - @inlinable public - func `as`(_:UnixMillisecond.Type) -> UnixMillisecond? - { - switch self - { - case .millisecond(let millisecond): - millisecond - default: - nil - } - } - /// Attempts to load an instance of ``Regex`` from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``regex(_:)``, - /// nil otherwise. - @inlinable public - func `as`(_:BSON.Regex.Type) -> BSON.Regex? - { - switch self - { - case .regex(let regex): - regex - default: - nil - } - } - /// Attempts to load an instance of ``String`` from this variant. - /// Its UTF-8 code units will be validated (and repaired if needed). - /// - /// - Returns: - /// The payload of this variant, decoded to a ``String``, if it matches - /// either ``string(_:)`` or ``javascript(_:)``, nil - /// otherwise. - /// - /// > Complexity: - /// O(*n*), where *n* is the length of the string. - @inlinable public - func `as`(_:String.Type) -> String? - { - self.utf8?.description - } -} -extension BSON.AnyValue -{ - /// Attempts to load an explicit ``null`` from this variant. - /// - /// - Returns: - /// A (the) instance of ``Null`` if this variant is ``null``, nil otherwise. - @inlinable public - func `as`(_:BSON.Null.Type) -> BSON.Null? - { - switch self - { - case .null: .init() - default: nil - } - } - /// Attempts to load a ``max`` key from this variant. - /// - /// - Returns: - /// A (the) instance of ``Max`` if this variant is ``max``, nil otherwise. - @inlinable public - func `as`(_:BSON.Max.Type) -> BSON.Max? - { - switch self - { - case .max: .init() - default: nil - } - } - /// Attempts to load a ``min`` key from this variant. - /// - /// - Returns: - /// A (the) instance of ``min`` if this variant is ``min``, nil otherwise. - @inlinable public - func `as`(_:BSON.Min.Type) -> BSON.Min? - { - switch self - { - case .min: .init() - default: nil - } - } -} -extension BSON.AnyValue -{ - /// Attempts to unwrap a binary array from this variant. - /// - /// - Returns: The payload of this variant if it matches ``binary(_:)``, - /// nil otherwise. - /// - /// > Complexity: O(1). - @inlinable public - var binary:BSON.BinaryView>? - { - switch self - { - case .binary(let binary): - binary - default: - nil - } - } - /// Attempts to unwrap a document from this variant. - /// - /// - Returns: The payload of this variant if it matches ``document(_:)`` - /// **or** ``list(_:)``, nil otherwise. - /// - /// If the variant was a list, the string keys of the returned document are likely - /// (but not guaranteed) to be the list indices encoded as base-10 strings, without - /// leading zeros. - /// - /// > Complexity: O(1). - @inlinable public - var document:BSON.Document? - { - switch self - { - case .document(let document): document - case .list(let list): .init(list: list) - default: nil - } - } - /// Attempts to unwrap a list from this variant. - /// - /// - Returns: - /// The payload of this variant if it matches ``list(_:)``, - /// nil otherwise. - /// - /// > Complexity: O(1). - @inlinable public - var list:BSON.List? - { - switch self - { - case .list(let list): list - default: nil - } - } - /// Attempts to unwrap an instance of ``UTF8View`` from this variant. Its UTF-8 - /// code units will *not* be validated, which allowes this method to return - /// in constant time. - /// - /// - Returns: - /// The payload of this variant if it matches either ``string(_:)`` - /// or ``javascript(_:)``, nil otherwise. - /// - /// > Complexity: O(1). - @inlinable public - var utf8:BSON.UTF8View>? - { - switch self - { - case .javascript(let code): code - case .string(let code): code - default: nil - } - } -} - -extension BSON.AnyValue:ExpressibleByStringLiteral, - ExpressibleByArrayLiteral, - ExpressibleByExtendedGraphemeClusterLiteral, - ExpressibleByUnicodeScalarLiteral, - ExpressibleByDictionaryLiteral -{ - @inlinable public - init(stringLiteral:String) - { - self = .string(.init(from: stringLiteral)) - } - @inlinable public - init(arrayLiteral:Self...) - { - self = .list(.init(elements: arrayLiteral)) - } - @inlinable public - init(dictionaryLiteral:(BSON.Key, Self)...) - { - self = .document(.init(fields: dictionaryLiteral)) - } -} - -extension BSON.AnyValue:ExpressibleByFloatLiteral -{ - @inlinable public - init(floatLiteral:Double) - { - self = .double(floatLiteral) - } -} -extension BSON.AnyValue:ExpressibleByIntegerLiteral -{ - /// Creates an instance initialized to the specified integer value. - /// It will be an ``int32(_:)`` value if it fits, otherwise it will - /// be an ``int64(_:)``. - /// - /// Although MongoDB uses ``Int32`` as its default integer type, - /// this library infers integer literals to be of type ``Int`` for - /// consistency with the rest of the Swift language. - @inlinable public - init(integerLiteral:Int) - { - if let int32:Int32 = .init(exactly: integerLiteral) - { - self = .int32(int32) - } - else - { - self = .int64(Int64.init(integerLiteral)) - } - } -} -extension BSON.AnyValue:ExpressibleByBooleanLiteral -{ - @inlinable public - init(booleanLiteral:Bool) - { - self = .bool(booleanLiteral) - } -} diff --git a/Sources/BSONABI/BSON.Decoder.swift b/Sources/BSONABI/BSON.Decoder.swift deleted file mode 100644 index 37aca12e..00000000 --- a/Sources/BSONABI/BSON.Decoder.swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON -{ - public - protocol Decoder - { - init(parsing bson:borrowing AnyValue) throws - } -} diff --git a/Sources/BSONABI/BSON.Encoder.swift b/Sources/BSONABI/BSON.Encoder.swift deleted file mode 100644 index 9b4d7b23..00000000 --- a/Sources/BSONABI/BSON.Encoder.swift +++ /dev/null @@ -1,16 +0,0 @@ -extension BSON -{ - public - protocol Encoder - { - associatedtype Frame:BufferFrame - - static - var frame:Frame { get } - - init(_:consuming Output) - - consuming - func move() -> Output - } -} diff --git a/Sources/BSONABI/BSON.TypeError.swift b/Sources/BSONABI/BSON.TypeError.swift deleted file mode 100644 index a369fa73..00000000 --- a/Sources/BSONABI/BSON.TypeError.swift +++ /dev/null @@ -1,24 +0,0 @@ -extension BSON -{ - /// A variant code did not encode a valid BSON type. - @frozen public - struct TypeError:Equatable, Error - { - public - let code:UInt8 - - @inlinable public - init(invalid code:UInt8) - { - self.code = code - } - } -} -extension BSON.TypeError:CustomStringConvertible -{ - public - var description:String - { - "invalid variant type code (\(self.code))" - } -} diff --git a/Sources/BSONABI/BSON.TypecastError.swift b/Sources/BSONABI/BSON.TypecastError.swift deleted file mode 100644 index 108c8eea..00000000 --- a/Sources/BSONABI/BSON.TypecastError.swift +++ /dev/null @@ -1,24 +0,0 @@ -extension BSON -{ - /// A decoder failed to cast a variant to an expected value type. - @frozen public - struct TypecastError:Equatable, Error - { - public - let variant:AnyType - - @inlinable public - init(invalid variant:AnyType) - { - self.variant = variant - } - } -} -extension BSON.TypecastError:CustomStringConvertible -{ - public - var description:String - { - "cannot cast variant of type '\(self.variant)' to type '\(Value.self)'" - } -} diff --git a/Sources/BSONABI/BSON.swift b/Sources/BSONABI/BSON.swift deleted file mode 100644 index 35da0206..00000000 --- a/Sources/BSONABI/BSON.swift +++ /dev/null @@ -1,5 +0,0 @@ -/// The namespace for all BSON types. -@frozen public -enum BSON -{ -} diff --git a/Sources/BSONABI/BSONRepresentable.swift b/Sources/BSONABI/BSONRepresentable.swift deleted file mode 100644 index b84ea8f8..00000000 --- a/Sources/BSONABI/BSONRepresentable.swift +++ /dev/null @@ -1,9 +0,0 @@ -public -protocol BSONRepresentable -{ - associatedtype BSONRepresentation - - init(_ bson:BSONRepresentation) - - var bson:BSONRepresentation { get } -} diff --git a/Sources/BSONABI/Fields/BSON.FieldEncoder.swift b/Sources/BSONABI/Fields/BSON.FieldEncoder.swift deleted file mode 100644 index 76433dbe..00000000 --- a/Sources/BSONABI/Fields/BSON.FieldEncoder.swift +++ /dev/null @@ -1,161 +0,0 @@ -import UnixTime - -extension BSON -{ - /// A type that can serialize any BSON container element. - @frozen public - struct FieldEncoder - { - public - let key:Key - public - var output:BSON.Output - - @inlinable public - init(key:Key, output:BSON.Output) - { - self.key = key - self.output = output - } - } -} -extension BSON.FieldEncoder -{ - /// Writes the given metatype value and ``key`` to the output buffer. - @inlinable mutating - func begin(_ type:BSON.AnyType) - { - self.output.serialize(type: type) - self.output.serialize(cString: self.key.rawValue) - } -} -extension BSON.FieldEncoder -{ - @inlinable public mutating - func encode(double:Double) - { - self.begin(.double) - self.output.serialize(integer: double.bitPattern) - } - @inlinable public mutating - func encode(id:BSON.Identifier) - { - self.begin(.id) - self.output.serialize(id: id) - } - @inlinable public mutating - func encode(bool:Bool) - { - self.begin(.bool) - self.output.append(bool ? 1 : 0) - } - @inlinable public mutating - func encode(millisecond:UnixMillisecond) - { - self.begin(.millisecond) - self.output.serialize(integer: millisecond.index) - } - @inlinable public mutating - func encode(regex:BSON.Regex) - { - self.begin(.regex) - self.output.serialize(cString: regex.pattern) - self.output.serialize(cString: regex.options.description) - } - @inlinable public mutating - func encode(int32:Int32) - { - self.begin(.int32) - self.output.serialize(integer: int32) - } - @inlinable public mutating - func encode(timestamp:BSON.Timestamp) - { - self.begin(.timestamp) - self.output.serialize(integer: timestamp.value) - } - @inlinable public mutating - func encode(int64:Int64) - { - self.begin(.int64) - self.output.serialize(integer: int64) - } - @inlinable public mutating - func encode(decimal128:BSON.Decimal128) - { - self.begin(.decimal128) - self.output.serialize(integer: decimal128.low) - self.output.serialize(integer: decimal128.high) - } - @inlinable public mutating - func encode(max:BSON.Max) - { - self.begin(.max) - } - @inlinable public mutating - func encode(min:BSON.Min) - { - self.begin(.min) - } - @inlinable public mutating - func encode(null:BSON.Null) - { - self.begin(.null) - } - - @inlinable public mutating - func encode(binary:BSON.BinaryView>) - { - self.begin(.binary) - self.output.serialize(binary: binary) - } - - @inlinable public mutating - func encode(document:BSON.Document) - { - self.begin(.document) - self.output.serialize(document: document) - } - @inlinable public mutating - func encode(list:BSON.List) - { - self.begin(.list) - self.output.serialize(list: list) - } - - @inlinable public mutating - func encode(string:BSON.UTF8View>) - { - self.begin(.string) - self.output.serialize(utf8: string) - } - @inlinable public mutating - func encode(javascript:BSON.UTF8View>) - { - self.begin(.javascript) - self.output.serialize(utf8: javascript) - } -} -extension BSON.FieldEncoder -{ - /// Writes the stored type code and ``key`` to the output buffer, temporarily rebinds - /// the output’s storage buffer to an encoder of the specified type, and brackets any - /// newly-written bytes with the appropriate headers or trailers. - /// - /// A complete frame will always be written to the output buffer, even if the coroutine - /// performs no writes. - @inlinable public - subscript(as _:Encoder.Type = Encoder.self) -> Encoder where Encoder:BSON.Encoder - { - mutating _read - { - self.begin(Encoder.frame.type) - yield self.output[in: Encoder.Frame.self][as: Encoder.self] - } - _modify - { - self.begin(Encoder.frame.type) - yield &self.output[in: Encoder.Frame.self][as: Encoder.self] - } - } -} diff --git a/Sources/BSONABI/Fields/BSON.Key.swift b/Sources/BSONABI/Fields/BSON.Key.swift deleted file mode 100644 index be99ee7f..00000000 --- a/Sources/BSONABI/Fields/BSON.Key.swift +++ /dev/null @@ -1,61 +0,0 @@ -extension BSON -{ - /// A BSON field key. This type wraps a ``rawValue`` that is - /// guaranteed to never contain null bytes. (Null bytes in a - /// BSON field key can be exploited to perform SQL injection.) - @frozen public - struct Key:Hashable, RawRepresentable, Sendable - { - public - let rawValue:String - - @inlinable public - init(rawValue:String) - { - precondition(!rawValue.utf8.contains(0)) - self.rawValue = rawValue - } - } -} -extension BSON.Key -{ - @inlinable public - init(index:Int) - { - self.init(rawValue: index.description) - } - @inlinable public - init(_ other:some RawRepresentable) - { - self.init(rawValue: other.rawValue) - } - public - init(_ codingKey:some CodingKey) - { - self.init(rawValue: codingKey.stringValue) - } -} -extension BSON.Key:Comparable -{ - @inlinable public static - func < (lhs:Self, rhs:Self) -> Bool - { - lhs.rawValue < rhs.rawValue - } -} -extension BSON.Key:CustomStringConvertible -{ - @inlinable public - var description:String - { - self.rawValue - } -} -extension BSON.Key:ExpressibleByStringLiteral, ExpressibleByStringInterpolation -{ - @inlinable public - init(stringLiteral:String) - { - self.init(rawValue: stringLiteral) - } -} diff --git a/Sources/BSONABI/IO/BSON.BufferFrame.swift b/Sources/BSONABI/IO/BSON.BufferFrame.swift deleted file mode 100644 index 6e960831..00000000 --- a/Sources/BSONABI/IO/BSON.BufferFrame.swift +++ /dev/null @@ -1,12 +0,0 @@ -extension BSON -{ - /// A type that augments a ``BufferFrameType`` conformance with a BSON metatype value. This - /// is a derived protocol because it is sometimes useful to repurpose the BSON frame parsing - /// machinery for additional (fictional) frame types that never appear in BSON data. - public - protocol BufferFrame:BufferFrameType - { - /// The BSON metatype value this buffer frame is associated with. - var type:AnyType { get } - } -} diff --git a/Sources/BSONABI/IO/BSON.BufferFrameType.swift b/Sources/BSONABI/IO/BSON.BufferFrameType.swift deleted file mode 100644 index 9141d14d..00000000 --- a/Sources/BSONABI/IO/BSON.BufferFrameType.swift +++ /dev/null @@ -1,37 +0,0 @@ -extension BSON -{ - /// A type that specifies the layout of a variable-length BSON view. - /// Parsers use conforming types to decide how to interpret BSON - /// length headers read from input data. - public - protocol BufferFrameType - { - /// A trailing byte to append, if any. - static - var trailer:UInt8? { get } - - /// The number of (conceptual) bytes in the frame prefix of the type - /// this frame type is associated with. - /// - /// This can be zero if the frame’s length header does not include its - /// own length, and can be positive if the length header skips additional - /// bytes before it starts counting. - static - var skipped:Int { get } - } -} -extension BSON.BufferFrameType -{ - /// The number of (conceptual) bytes in the frame suffix of the type - /// this frame type is associated with. This is 0 if ``trailer`` is - /// nil, and 1 otherwise. - @inlinable internal static - var suffix:Int - { - switch self.trailer - { - case nil: 0 - case _?: 1 - } - } -} diff --git a/Sources/BSONABI/IO/BSON.BufferTraversable.swift b/Sources/BSONABI/IO/BSON.BufferTraversable.swift deleted file mode 100644 index 3bd3f107..00000000 --- a/Sources/BSONABI/IO/BSON.BufferTraversable.swift +++ /dev/null @@ -1,32 +0,0 @@ -extension BSON -{ - /// A framed type that BSON parsers can traverse in constant time. - /// - /// BSON parsers typically parse conforming types by reading a length - /// header from raw input data, and using it to slice the input, - /// ideally without copying backing storage. The interpretation of the - /// length header is specified by the ``BufferTraversable/Frame`` type requirement, and - /// the exact slicing behavior is determined by the implementation’s - /// ``init(slicing:)`` witness. - public - protocol BufferTraversable - { - /// The type specifying how parsers should interpret the conforming - /// type’s inline frame header when it appears in raw input data. - associatedtype Frame:BufferFrame - - /// Receives a collection of bytes encompassing the bytes backing - /// this value, after stripping the length header and frame suffix, - /// but keeping any portions of the frame prefix that are not part - /// of the length header. - /// - /// The implementation may slice the argument, but should do so in - /// O(1) time. - init(slicing:ArraySlice) throws - - /// The slice of bytes constituting the opaque content of this view. The conforming type - /// defines what portion of the original buffer this slice includes, and it may not - /// cover the entirety of the argument originally passed to ``init(slicing:)``. - var bytes:ArraySlice { get } - } -} diff --git a/Sources/BSONABI/IO/BSON.HeaderError.swift b/Sources/BSONABI/IO/BSON.HeaderError.swift deleted file mode 100644 index 92b83bd2..00000000 --- a/Sources/BSONABI/IO/BSON.HeaderError.swift +++ /dev/null @@ -1,26 +0,0 @@ -extension BSON -{ - @frozen public - struct HeaderError:Equatable, Error where Frame:BufferFrameType - { - public - let length:Int - - @inlinable public - init(length:Int) - { - self.length = length - } - } -} -extension BSON.HeaderError:CustomStringConvertible -{ - public - var description:String - { - """ - length declared in header (\(self.length)) is less than \ - the minimum for '\(Frame.self)' (\(Frame.suffix - Frame.skipped) bytes) - """ - } -} diff --git a/Sources/BSONABI/IO/BSON.Input.swift b/Sources/BSONABI/IO/BSON.Input.swift deleted file mode 100644 index b721f703..00000000 --- a/Sources/BSONABI/IO/BSON.Input.swift +++ /dev/null @@ -1,286 +0,0 @@ -import UnixTime - -extension BSON -{ - /// A type for managing BSON parsing state. Most users of this module - /// should not need to interact with it directly. - @frozen public - struct Input:Sendable - { - public - let source:ArraySlice - public - var index:Int - - /// Creates a parsing input view over the given `source` data, - /// and initializes its ``index`` to the start index of the `source`. - @inlinable public - init(_ source:ArraySlice) - { - self.source = source - self.index = self.source.startIndex - } - } -} -extension BSON.Input -{ - /// Consumes and returns a single byte from this parsing input. - @inlinable public mutating - func next() -> UInt8? - { - guard self.index < self.source.endIndex - else - { - return nil - } - defer - { - self.source.formIndex(after: &self.index) - } - - return self.source[self.index] - } - /// Advances the current index until encountering the specified `byte`. - /// After this method returns, ``index`` points to the byte after - /// the matched byte. - /// - /// - Returns: - /// A range covering the bytes skipped. The upper-bound of - /// the range points to the matched byte. - @discardableResult - @inlinable public mutating - func parse(through byte:UInt8) throws -> Range - { - let start:Int = self.index - while self.index < self.source.endIndex - { - defer - { - self.source.formIndex(after: &self.index) - } - if self.source[self.index] == byte - { - return start ..< self.index - } - } - throw BSON.InputError.init(expected: .byte(byte)) - } - /// Parses a null-terminated string. - @inlinable public mutating - func parse(as _:String.Type = String.self) throws -> String - { - .init(decoding: self.source[try self.parse(through: 0x00)], as: Unicode.UTF8.self) - } - /// Parses a MongoDB object identifier. - @inlinable public mutating - func parse(as _:BSON.Identifier.Type = BSON.Identifier.self) throws -> BSON.Identifier - { - let start:Int = self.index - if let end:Int = self.source.index(self.index, offsetBy: 12, - limitedBy: self.source.endIndex) - { - self.index = end - return .init { $0.copyBytes(from: self.source[start ..< end]) } - } - else - { - throw self.expected(.bytes(12)) - } - } - /// Parses a boolean. - @inlinable public mutating - func parse(as _:Bool.Type = Bool.self) throws -> Bool - { - switch self.next() - { - case 0?: - return false - case 1?: - return true - case let code?: - throw BSON.BooleanSubtypeError.init(invalid: code) - case nil: - throw BSON.InputError.init(expected: .bytes(1)) - } - } - @inlinable public mutating - func parse(as _:BSON.Decimal128.Type = BSON.Decimal128.self) throws -> BSON.Decimal128 - { - let low:UInt64 = try self.parse(as: UInt64.self) - let high:UInt64 = try self.parse(as: UInt64.self) - return .init(high: high, low: low) - } - @inlinable public mutating - func parse(as _:UnixMillisecond.Type = UnixMillisecond.self) throws -> UnixMillisecond - { - .init(index: try self.parse(as: Int64.self)) - } - @inlinable public mutating - func parse(as _:BSON.Regex.Type = BSON.Regex.self) throws -> BSON.Regex - { - let pattern:String = try self.parse(as: String.self) - let options:String = try self.parse(as: String.self) - return try .init(pattern: pattern, options: options) - } - /// Parses a little-endian integer. - @inlinable public mutating - func parse(as _:LittleEndian.Type = LittleEndian.self) throws -> LittleEndian - where LittleEndian:FixedWidthInteger - { - let start:Int = self.index - if let end:Int = self.source.index(self.index, - offsetBy: MemoryLayout.size, - limitedBy: self.source.endIndex) - { - self.index = end - return withUnsafeTemporaryAllocation( - byteCount: MemoryLayout.size, - alignment: MemoryLayout.alignment) - { - $0.copyBytes(from: self.source[start ..< end]) - return .init(littleEndian: $0.load(as: LittleEndian.self)) - } - } - else - { - throw self.expected(.bytes(MemoryLayout.size)) - } - } - - @inlinable public mutating - func parse(_:Frame.Type) throws -> ArraySlice - where Frame:BSON.BufferFrameType - { - let header:Int = .init(try self.parse(as: Int32.self)) - let stride:Int = header + Frame.skipped - let count:Int = stride - Frame.suffix - if count < 0 - { - throw BSON.HeaderError.init(length: header) - } - let start:Int = self.index - if let end:Int = self.source.index(start, offsetBy: stride, - limitedBy: self.source.endIndex) - { - self.index = end - return self.source[start ..< self.source.index(start, offsetBy: count)] - } - else - { - throw self.expected(.bytes(stride)) - } - } - - /// Parses a traversable BSON element. The output is typically opaque, - /// which allows decoders to skip over regions of a BSON document. - @inlinable public mutating - func parse(as _:View.Type = View.self) throws -> View - where View:BSON.BufferTraversable - { - try .init(slicing: try self.parse(View.Frame.self)) - } - - /// Returns a slice of the input from the current ``index`` to the end - /// of the input. Accessing this property does not affect the current - /// ``index``. - @inlinable public - var remaining:ArraySlice - { - self.source.suffix(from: self.index) - } - - /// Asserts that there is no input remaining. - @inlinable public - func finish() throws - { - if self.index != self.source.endIndex - { - throw self.expected(.end) - } - } - - /// Creates an ``InputError`` with appropriate context for the specified expectation. - @inlinable public - func expected(_ expectation:BSON.InputError.Expectation) -> BSON.InputError - { - .init(expected: expectation, - encountered: self.source.distance(from: self.index, to: self.source.endIndex)) - } -} - -extension BSON.Input -{ - /// Parses a variant BSON value, assuming it is of the specified `variant` type. - @inlinable public mutating - func parse(variant:BSON.AnyType) throws -> BSON.AnyValue - { - switch variant - { - case .double: - return .double(.init(bitPattern: try self.parse(as: UInt64.self))) - - case .string: - return .string(try self.parse(as: BSON.UTF8View>.self)) - - case .document: - return .document(try self.parse(as: BSON.Document.self)) - - case .list: - return .list(try self.parse(as: BSON.List.self)) - - case .binary: - return .binary(try self.parse(as: BSON.BinaryView>.self)) - - case .null: - return .null - - case .id: - return .id(try self.parse(as: BSON.Identifier.self)) - - case .bool: - return .bool(try self.parse(as: Bool.self)) - - case .millisecond: - return .millisecond(try self.parse(as: UnixMillisecond.self)) - - case .regex: - return .regex(try self.parse(as: BSON.Regex.self)) - - case .pointer: - let database:BSON.UTF8View> = try self.parse( - as: BSON.UTF8View>.self) - let object:BSON.Identifier = try self.parse( - as: BSON.Identifier.self) - return .pointer(database, object) - - case .javascript: - return .javascript(try self.parse(as: BSON.UTF8View>.self)) - - case .javascriptScope: - // possible micro-optimization here - let _:Int32 = try self.parse(as: Int32.self) - let code:BSON.UTF8View> = try self.parse( - as: BSON.UTF8View>.self) - let scope:BSON.Document = try self.parse( - as: BSON.Document.self) - return .javascriptScope(scope, code) - - case .int32: - return .int32(try self.parse(as: Int32.self)) - - case .timestamp: - return .timestamp(.init(try self.parse(as: UInt64.self))) - - case .int64: - return .int64(try self.parse(as: Int64.self)) - - case .decimal128: - return .decimal128(try self.parse(as: BSON.Decimal128.self)) - - case .max: - return .max - case .min: - return .min - } - } -} diff --git a/Sources/BSONABI/IO/BSON.InputError.Expectation.swift b/Sources/BSONABI/IO/BSON.InputError.Expectation.swift deleted file mode 100644 index 09702b77..00000000 --- a/Sources/BSONABI/IO/BSON.InputError.Expectation.swift +++ /dev/null @@ -1,29 +0,0 @@ -extension BSON.InputError -{ - @frozen public - enum Expectation:Equatable, Sendable - { - /// The input should have yielded end-of-input. - case end - /// The input should have yielded a terminator byte that never appeared. - case byte(UInt8) - /// The input should have yielded a particular number of bytes. - case bytes(Int) - } -} -extension BSON.InputError.Expectation:CustomStringConvertible -{ - public - var description:String - { - switch self - { - case .end: - "end-of-input" - case .byte(let byte): - "terminator byte (\(byte))" - case .bytes(let count): - "\(count) byte(s)" - } - } -} diff --git a/Sources/BSONABI/IO/BSON.InputError.swift b/Sources/BSONABI/IO/BSON.InputError.swift deleted file mode 100644 index 7c1c9244..00000000 --- a/Sources/BSONABI/IO/BSON.InputError.swift +++ /dev/null @@ -1,31 +0,0 @@ -extension BSON -{ - /// A parser did not receive the expected amount of input. - @frozen public - struct InputError:Equatable, Error - { - /// What the input should have yielded. - public - let expected:Expectation - /// The number of bytes available in the input. - public - let encountered:Int - - @inlinable public - init(expected:Expectation, encountered:Int = 0) - { - self.expected = expected - self.encountered = encountered - } - } -} -extension BSON.InputError:CustomStringConvertible -{ - public - var description:String - { - self.encountered == 0 ? - "expected \(self.expected)" : - "expected \(self.expected), encountered \(self.encountered) byte(s)" - } -} diff --git a/Sources/BSONABI/IO/BSON.Output.swift b/Sources/BSONABI/IO/BSON.Output.swift deleted file mode 100644 index 54eec7cb..00000000 --- a/Sources/BSONABI/IO/BSON.Output.swift +++ /dev/null @@ -1,307 +0,0 @@ -import UnixTime - -extension BSON -{ - @frozen public - struct Output:Sendable - { - public - var destination:ArraySlice - - /// Create an output with a pre-allocated destination buffer. The buffer - /// does *not* need to be empty, and existing data will not be cleared. - @inlinable public - init(preallocated destination:ArraySlice) - { - self.destination = destination - } - - /// Create an empty output, reserving enough space for the specified - /// number of bytes in the destination buffer. - /// - /// The size hint is only effective if `Destination` provides a real, - /// non-defaulted witness for - /// ``RangeReplaceableCollection.reserveCapacity(_:) [2YKV1]``. - @inlinable public - init(capacity:Int) - { - self.destination = .init() - self.destination.reserveCapacity(capacity) - } - } -} -extension BSON.Output:BSON.OutputStream -{ - /// Reserves another `bytes` worth of capacity in the output destination, in addition to the - /// bytes already present. - @inlinable public mutating - func reserve(another bytes:Int) - { - self.destination.reserveCapacity(self.destination.count + bytes) - } - - /// Appends a single byte to the output destination. - @inlinable public mutating - func append(_ byte:UInt8) - { - self.destination.append(byte) - } - /// Appends a sequence of bytes to the output destination. - @inlinable public mutating - func append(_ bytes:some Sequence) - { - self.destination.append(contentsOf: bytes) - } -} -extension BSON.Output -{ - @inlinable public mutating - func serialize(type:BSON.AnyType) - { - self.append(type.rawValue) - } - - @inlinable public mutating - func serialize(id:BSON.Identifier) - { - withUnsafeBytes(of: id.bitPattern) - { - self.append($0) - } - } -} -extension BSON.Output -{ - /// Serializes the given variant value, without encoding its type. - @inlinable public mutating - func serialize(variant:BSON.AnyValue) - { - switch variant - { - case .double(let double): - self.serialize(integer: double.bitPattern) - - case .string(let string): - self.serialize(utf8: string) - - case .document(let document): - self.serialize(document: document) - - case .list(let list): - self.serialize(list: list) - - case .binary(let binary): - self.serialize(binary: binary) - - case .null: - break - - case .id(let id): - self.serialize(id: id) - - case .bool(let bool): - self.append(bool ? 1 : 0) - - case .millisecond(let millisecond): - self.serialize(integer: millisecond.index) - - case .regex(let regex): - self.serialize(cString: regex.pattern) - self.serialize(cString: regex.options.description) - - case .pointer(let database, let id): - self.serialize(utf8: database) - self.serialize(id: id) - - case .javascript(let code): - self.serialize(utf8: code) - - case .javascriptScope(let scope, let code): - let size:Int32 = 4 + Int32.init(scope.size) + Int32.init(code.size) - self.serialize(integer: size) - self.serialize(utf8: code) - self.serialize(document: scope) - - case .int32(let int32): - self.serialize(integer: int32) - - case .timestamp(let timestamp): - self.serialize(integer: timestamp.value) - - case .int64(let int64): - self.serialize(integer: int64) - - case .decimal128(let decimal): - self.serialize(integer: decimal.low) - self.serialize(integer: decimal.high) - - case .max: - break - case .min: - break - } - } - /// Serializes the raw type code of the given variant value, followed by - /// the field key (with a trailing null byte), followed by the variant value - /// itself. - @inlinable public mutating - func serialize(key:BSON.Key, value:BSON.AnyValue) - { - self.serialize(type: value.type) - self.serialize(cString: key.rawValue) - self.serialize(variant: value) - } - @inlinable public mutating - func serialize(fields:some Sequence<(key:BSON.Key, value:BSON.AnyValue)>) - { - for (key, value):(BSON.Key, BSON.AnyValue) in fields - { - self.serialize(key: key, value: value) - } - } -} -extension BSON.Output -{ - /// Temporarily rebinds this output’s storage buffer to a field encoder. Field encoding is - /// always lazy, so the getter has no effects. - @inlinable public - subscript(with key:BSON.Key) -> BSON.FieldEncoder - { - get - { - .init(key: key, output: self) - } - _modify - { - var field:BSON.FieldEncoder = self[with: key] - self = .init(preallocated: []) - defer { self = field.output } - yield &field - } - } -} -extension BSON.Output -{ - /// Temporarily rebinds this output’s storage buffer to an encoder of the specified type, - /// bracketing it with the appropriate headers or trailers. - /// - /// - See also: ``subscript(as:)``. - @inlinable public - subscript(as _:Encoder.Type, in frame:BSON.DocumentFrame.Type) -> Encoder - where Encoder:BSON.Encoder - { - mutating _read - { - yield self[in: frame][as: Encoder.self] - } - _modify - { - yield &self[in: frame][as: Encoder.self] - } - } - /// Temporarily rebinds this output’s storage buffer to an encoder of the specified type. - /// This function does not add any headers or trailers; to emit a complete BSON frame, - /// mutate through ``subscript(as:in:)``. - /// - /// Some encoders may write on ``BSON.Encoder/init(_:)`` to preserve application-level - /// invariants, so type rebinding can have mutating effects even if the coroutine performs - /// no writes. - /// - /// - See also: ``subscript(with:)``. - @inlinable public - subscript(as _:Encoder.Type) -> Encoder where Encoder:BSON.Encoder - { - mutating _read - { - let encoder:Encoder = .init(consume self) - defer { self = encoder.move() } - yield encoder - } - _modify - { - var encoder:Encoder = .init(consume self) - defer { self = encoder.move() } - yield &encoder - } - } - - @inlinable - subscript(in frame:(some BSON.BufferFrame).Type) -> Self - { - mutating _read - { - let header:Int = self.destination.endIndex - - self.append(0x00) - self.append(0x00) - self.append(0x00) - self.append(0x00) - - defer - { - let written:Int - - if let trailer:UInt8 = frame.trailer - { - self.append(trailer) - written = 1 - } - else - { - written = 0 - } - - self.update(length: written - frame.skipped - 4, at: header) - } - - yield self - } - - _modify - { - let header:Int = self.destination.endIndex - - // make room for the length header - self.append(0x00) - self.append(0x00) - self.append(0x00) - self.append(0x00) - - defer - { - /// Make sure the caller has not cleared the buffer. - assert(self.destination.index(header, offsetBy: 4) <= self.destination.endIndex) - - if let trailer:UInt8 = frame.trailer - { - self.append(trailer) - } - - let written:Int = self.destination.distance(from: header, - to: self.destination.endIndex) - - self.update(length: written - frame.skipped - 4, at: header) - } - - yield &self - } - } -} -extension BSON.Output -{ - /// Updates the length header at the specified `header` position to contain the given - /// `length` value, encoding it to the output stream in little-endian byte order. - @inlinable mutating - func update(length:Int, at header:Int) - { - withUnsafeBytes(of: Int32.init(length).littleEndian) - { - var index:Int = header - for byte:UInt8 in $0 - { - self.destination[index] = byte - self.destination.formIndex(after: &index) - } - } - } -} diff --git a/Sources/BSONABI/IO/BSON.OutputStream.swift b/Sources/BSONABI/IO/BSON.OutputStream.swift deleted file mode 100644 index 42f89882..00000000 --- a/Sources/BSONABI/IO/BSON.OutputStream.swift +++ /dev/null @@ -1,64 +0,0 @@ -extension BSON -{ - public - protocol OutputStream - { - mutating - func reserve(another bytes:Int) - - mutating - func append(_ byte:UInt8) - mutating - func append(_ bytes:some Sequence) - } -} -extension BSON.OutputStream -{ - /// Serializes the UTF-8 code units of a string as a c-string with a trailing - /// null byte. The `cString` must not contain null bytes. Use ``serialize(utf8:)`` - /// to serialize a string that contains interior null bytes. - @inlinable public mutating - func serialize(cString:String) - { - self.append(cString.utf8) - self.append(0x00) - } - /// Serializes a fixed-width integer in little-endian byte order. - @inlinable public mutating - func serialize(integer:some FixedWidthInteger) - { - withUnsafeBytes(of: integer.littleEndian) - { - self.append($0) - } - } - - @inlinable public mutating - func serialize(utf8:BSON.UTF8View>) - { - self.serialize(integer: utf8.header) - self.append(utf8.bytes) - self.append(0x00) - } - @inlinable public mutating - func serialize(binary:BSON.BinaryView>) - { - self.serialize(integer: binary.header) - self.append(binary.subtype.rawValue) - self.append(binary.bytes) - } - @inlinable public mutating - func serialize(document:BSON.Document) - { - self.serialize(integer: document.header) - self.append(document.bytes) - self.append(0x00) - } - @inlinable public mutating - func serialize(list:BSON.List) - { - self.serialize(integer: list.header) - self.append(list.bytes) - self.append(0x00) - } -} diff --git a/Sources/BSONABI/Primitives/BSON.BooleanSubtypeError.swift b/Sources/BSONABI/Primitives/BSON.BooleanSubtypeError.swift deleted file mode 100644 index ceaed475..00000000 --- a/Sources/BSONABI/Primitives/BSON.BooleanSubtypeError.swift +++ /dev/null @@ -1,24 +0,0 @@ -extension BSON -{ - /// A byte encoding a boolean value was not [`0`]() or [`1`](). - @frozen public - struct BooleanSubtypeError:Equatable, Error - { - public - let code:UInt8 - - @inlinable public - init(invalid code:UInt8) - { - self.code = code - } - } -} -extension BSON.BooleanSubtypeError:CustomStringConvertible -{ - public - var description:String - { - "invalid boolean subtype code (\(self.code))" - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Decimal128.swift b/Sources/BSONABI/Primitives/BSON.Decimal128.swift deleted file mode 100644 index 972272e5..00000000 --- a/Sources/BSONABI/Primitives/BSON.Decimal128.swift +++ /dev/null @@ -1,29 +0,0 @@ -extension BSON -{ - /// An opaque IEEE 754-2008 decimal. - /// - /// This library does not have access to decimal-aware facilities. - /// Therefore, `Decimal128` instances are not ``Comparable``, at least when - /// importing this module alone. - /// - /// Take caution when using this type’s ``Hashable`` and ``Equatable`` conformances. - /// Two `Decimal128` values can encode the same numeric value, yet compare unequal - /// under ``Equatable.==(_:_:)``. - @frozen public - struct Decimal128:Hashable, Equatable, Sendable - { - /// The low 64 bits of this decimal value. - public - var low:UInt64 - /// The high 64 bits of this decimal value. - public - var high:UInt64 - - @inlinable public - init(high:UInt64, low:UInt64) - { - self.high = high - self.low = low - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Document.swift b/Sources/BSONABI/Primitives/BSON.Document.swift deleted file mode 100644 index 02fd6066..00000000 --- a/Sources/BSONABI/Primitives/BSON.Document.swift +++ /dev/null @@ -1,185 +0,0 @@ -extension BSON -{ - /// The `Document` type models the “universal” BSON DSL. - /// - /// It is expected that more-specialized BSON DSLs will wrap an - /// instance of `Document`. - @frozen public - struct Document:Sendable - { - public - var output:BSON.Output - - /// Creates an empty document. - @inlinable public - init() - { - self.output = .init(preallocated: []) - } - - /// Stores the argument in ``bytes`` unchanged. - /// - /// > Complexity: O(1) - @inlinable public - init(bytes:ArraySlice) - { - self.output = .init(preallocated: bytes) - } - } -} -extension BSON.Document:BSON.BufferTraversable -{ - public - typealias Frame = BSON.DocumentFrame - - /// Stores the argument in ``bytes`` unchanged. Equivalent to ``init(bytes:)``. - /// - /// > Complexity: O(1) - @inlinable public - init(slicing bytes:ArraySlice) - { - self.init(bytes: bytes) - } - - /// The raw data backing this document. This slice *does not* include the trailing null byte - /// that typically appears after its inline field list. - @inlinable public - var bytes:ArraySlice { self.output.destination } -} -extension BSON.Document -{ - /// Indicates if this document contains no fields. - @inlinable public - var isEmpty:Bool { self.bytes.isEmpty } - - /// The length that would be encoded in this document’s prefixed header. - /// Equal to ``size``. - @inlinable public - var header:Int32 { .init(self.size) } - - /// The size of this document when encoded with its header and trailing - /// null byte. This *is* the same as the length encoded in the header itself. - @inlinable public - var size:Int { 5 + self.bytes.count } - - /// Rebinds the backing storage of this list to a ``BSON.Document``. This will cause the - /// list to be interpreted as a document with keys numbered from 0 in base-10. - @inlinable public - init(list:BSON.List) - { - self.init(bytes: list.bytes) - } - - @inlinable public mutating - func append(contentsOf other:Self) - { - self.output.append(other.bytes) - } -} -extension BSON.Document:Equatable -{ - /// Performs an exact byte-wise comparison on two documents. Does not parse or validate the - /// operands. Documents with the same fields in different orders will compare unequal! - @inlinable public static - func == (a:Self, b:Self) -> Bool { a.bytes.elementsEqual(b.bytes) } -} - -extension BSON.Document -{ - /// Parses this document into key-value pairs in order, yielding each key-value - /// pair to the provided closure. - /// - /// Unlike ``parse(_:)``, this method does not allocate storage for the parsed key-value - /// pairs. (But it does allocate storage to provide a ``String`` representation for - /// each visited key.) - /// - /// > Complexity: - /// O(*n*), where *n* is the size of this document’s backing storage. - @inlinable public - func parse(to decode:(CodingKey, BSON.AnyValue) throws -> ()) throws - where CodingKey:RawRepresentable - { - var input:BSON.Input = .init(self.bytes) - while let code:UInt8 = input.next() - { - let type:BSON.AnyType = try .init(code: code) - let key:String = try input.parse(as: String.self) - // We must parse the value always, even if we are ignoring the key - let value:BSON.AnyValue = try input.parse(variant: type) - - if let key:CodingKey = .init(rawValue: key) - { - try decode(key, value) - } - } - } - /// Splits this document’s inline key-value pairs into an array. - /// - /// Calling this convenience method is the same as calling ``parse(to:)`` and - /// collecting the yielded key-value pairs in an array. - /// - /// > Complexity: - /// O(*n*), where *n* is the size of this document’s backing storage. - @inlinable public - func parse( - _ transform:(_ key:CodingKey, _ value:BSON.AnyValue) throws -> T) throws -> [T] - where CodingKey:RawRepresentable - { - var elements:[T] = [] - try self.parse - { - elements.append(try transform($0, $1)) - } - return elements - } -} -extension BSON.Document:ExpressibleByDictionaryLiteral -{ - /// Creates a document containing the given fields, making two passes over - /// the list of fields in order to encode the output without reallocations. - /// The order of the fields will be preserved. - @inlinable public - init(fields:some Collection<(key:BSON.Key, value:BSON.AnyValue)>) - { - let size:Int = fields.reduce(0) { $0 + 2 + $1.key.rawValue.utf8.count + $1.value.size } - var output:BSON.Output = .init(capacity: size) - output.serialize(fields: fields) - - assert(output.destination.count == size, """ - precomputed size (\(size)) does not match output size (\(output.destination.count)) - """) - - self.init(bytes: output.destination) - } - - /// Creates a document containing a single key-value pair. - @inlinable public - init(key:BSON.Key, value:BSON.AnyValue) - { - self.init( - fields: CollectionOfOne<(key:BSON.Key, value:BSON.AnyValue)>.init((key, value))) - } - - @inlinable public - init(dictionaryLiteral:(BSON.Key, BSON.AnyValue)...) - { - self.init(fields: dictionaryLiteral) - } -} - -extension BSON.Document -{ - @available(*, deprecated, message: "BSON.Document is already a BSON.Document") - @inlinable public - init(_ bson:Self) - { - self = bson - } - - @available(*, deprecated, message: "BSON.Document is already a BSON.Document") - @inlinable public - init(bson:Self) - { - self = bson - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Identifier.swift b/Sources/BSONABI/Primitives/BSON.Identifier.swift deleted file mode 100644 index f7d8514c..00000000 --- a/Sources/BSONABI/Primitives/BSON.Identifier.swift +++ /dev/null @@ -1,225 +0,0 @@ -extension BSON -{ - /// A MongoDB object reference. This type models a MongoDB `ObjectId`. - /// - /// This type has reference semantics, but (needless to say) it is - /// completely unmanaged, as it is nothing more than a 96-bit integer. - /// - /// The type name is chosen to avoid conflict with Swift’s ``ObjectIdentifier``. - @frozen public - struct Identifier:Sendable - { - public - let bitPattern:(UInt32, UInt32, UInt32) - - /// Creates an identifier with the given bit pattern. Do not use this - /// initializer to create an identifier from integer literals; use - /// ``init(_:_:_:)``, which accounts for platform endianness, instead. - @inlinable internal - init(bitPattern:(UInt32, UInt32, UInt32)) - { - self.bitPattern = bitPattern - } - } -} -extension BSON.Identifier -{ - /// Creates an identifier with the given high-, middle-, and low-components. - /// The components are interpreted by platform endianness; therefore the values - /// stored into ``bitPattern`` may be different if the current host is not - /// big-endian. - @inlinable public - init(_ high:UInt32, _ middle:UInt32, _ low:UInt32) - { - self.init(bitPattern: (high.bigEndian, middle.bigEndian, low.bigEndian)) - } - /// Creates an identifier by delegating to the closure to initialize raw memory. - /// The buffer contains 12 bytes and will be interpreted as a 96-bit, big-endian - /// integer. - @inlinable public - init(with initialize:(_ memory:UnsafeMutableRawBufferPointer) throws -> ()) rethrows - { - let bitPattern:(UInt32, UInt32, UInt32) = try withUnsafeTemporaryAllocation( - byteCount: MemoryLayout<(UInt32, UInt32, UInt32)>.size, - alignment: MemoryLayout<(UInt32, UInt32, UInt32)>.alignment) - { - try initialize($0) - return $0.load(as: (UInt32, UInt32, UInt32).self) - } - - self.init(bitPattern: bitPattern) - } -} -extension BSON.Identifier -{ - /// The high 32 bits of this identifier. The high byte of this - /// integer is the byte at offset +0 of this identifier. - @inlinable public - var timestamp:UInt32 - { - .init(bigEndian: self.bitPattern.0) - } - /// The middle 32 bits of this identifier. The high byte of this - /// integer is the byte at offset +4 of this identifier. - @inlinable public - var middle:UInt32 - { - .init(bigEndian: self.bitPattern.1) - } - /// The low 32 bits of this identifier. The high byte of this - /// integer is the byte at offset +8 of this identifier. - @inlinable public - var low:UInt32 - { - .init(bigEndian: self.bitPattern.2) - } -} -extension BSON.Identifier:ExpressibleByIntegerLiteral -{ - @inlinable public - init(integerLiteral:StaticBigInt) - { - precondition(integerLiteral.signum() >= 0, - "BSON identifier literal cannot be negative") - precondition(integerLiteral.bitWidth <= 97, // +1 bit for “sign” bit - "BSON identifier literal overflows UInt96 (bit width: \(integerLiteral.bitWidth))") - - self.init - { - (bytes:UnsafeMutableRawBufferPointer) in - - var byte:Int = bytes.endIndex - var word:Int = 0 - while byte != bytes.startIndex - { - withUnsafeBytes(of: integerLiteral[word].bigEndian) - { - for value:UInt8 in $0.reversed() - { - byte = bytes.index(before: byte) - bytes[byte] = value - - if byte == bytes.startIndex - { - break - } - } - } - word += 1 - } - } - } -} -extension BSON.Identifier:CustomStringConvertible -{ - @inlinable public - var description:String - { - let unpadded:(String, String, String) = - ( - .init(self.timestamp, radix: 16), - .init(self.middle, radix: 16), - .init(self.low, radix: 16) - ) - let padding:(String, String, String) = - ( - "\(String.init(repeating: "0", count: 8 - unpadded.0.count))", - "\(String.init(repeating: "0", count: 8 - unpadded.1.count))", - "\(String.init(repeating: "0", count: 8 - unpadded.2.count))" - ) - return "0x\(padding.0)\(unpadded.0)_\(padding.1)\(unpadded.1)_\(padding.2)\(unpadded.2)" - } -} -extension BSON.Identifier -{ - public - typealias Seed = - ( - UInt8, - UInt8, - UInt8, - UInt8, - UInt8 - ) - public - typealias Ordinal = - ( - UInt8, - UInt8, - UInt8 - ) - - @inlinable public - init(timestamp:UInt32, seed:Seed, ordinal:Ordinal) - { - self.init(bitPattern: - ( - timestamp.bigEndian, - withUnsafeBytes(of: (seed.0, seed.1, seed.2, seed.3)) - { - $0.load(as: UInt32.self) - }, - withUnsafeBytes(of: (seed.4, ordinal.0, ordinal.1, ordinal.2)) - { - $0.load(as: UInt32.self) - } - )) - } - - /// The middle five bytes of this identifier. The first tuple element - /// is the byte at offset +4 of this identifier. - @inlinable public - var seed:Seed - { - withUnsafeBytes(of: self.bitPattern) - { - $0.load(fromByteOffset: 4, as: Seed.self) - } - } - - /// The last three bytes of this identifier. The first tuple element - /// is the byte at offset +9 of this identifier. - @inlinable public - var ordinal:Ordinal - { - withUnsafeBytes(of: self.bitPattern) - { - $0.load(fromByteOffset: 9, as: Ordinal.self) - } - } -} -extension BSON.Identifier:Equatable -{ - @inlinable public static - func == (lhs:Self, rhs:Self) -> Bool - { - lhs.bitPattern == rhs.bitPattern - } -} -extension BSON.Identifier:Comparable -{ - /// Compares the bytes of this identifier in lexicographical order. - /// This is the same as performing a lexicographic numeric comparison - /// on (``timestamp``, ``middle``, ``low``). Depending on platform - /// endianness, this may be different from performing a lexicographic - /// numeric comparison on ``bitPattern`` directly. - @inlinable public static - func < (lhs:Self, rhs:Self) -> Bool - { - (lhs.timestamp, lhs.middle, lhs.low) < - (rhs.timestamp, rhs.middle, rhs.low) - } -} -extension BSON.Identifier:Hashable -{ - /// Hashes the bytes of this identifier in the order they are stored - /// in memory. - @inlinable public - func hash(into hasher:inout Hasher) - { - withUnsafeBytes(of: self.bitPattern) - { - hasher.combine(bytes: $0) - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.IntegerOverflowError.swift b/Sources/BSONABI/Primitives/BSON.IntegerOverflowError.swift deleted file mode 100644 index d90fce4b..00000000 --- a/Sources/BSONABI/Primitives/BSON.IntegerOverflowError.swift +++ /dev/null @@ -1,33 +0,0 @@ -extension BSON -{ - /// An overflow occurred while casting an integer value to a desired type. - @frozen public - enum IntegerOverflowError:Equatable, Error where Overflowed:FixedWidthInteger - { - /// An overflow occurred while casting an ``Int32`` to an - /// instance of `Overflowed`. - case int32(Int32) - /// An overflow occurred while casting an ``Int64`` to an - /// instance of `Overflowed`. - case int64(Int64) - /// An overflow occurred while casting a ``UInt64`` to an - /// instance of `Overflowed`. - case uint64(UInt64) - } -} -extension BSON.IntegerOverflowError:CustomStringConvertible -{ - public - var description:String - { - switch self - { - case .int32 (let value): - "value '\(value)' of type 'int32' overflows decoded type '\(Overflowed.self)'" - case .int64 (let value): - "value '\(value)' of type 'int64' overflows decoded type '\(Overflowed.self)'" - case .uint64(let value): - "value '\(value)' of type 'uint64' overflows decoded type '\(Overflowed.self)'" - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.List.swift b/Sources/BSONABI/Primitives/BSON.List.swift deleted file mode 100644 index 6836a4d9..00000000 --- a/Sources/BSONABI/Primitives/BSON.List.swift +++ /dev/null @@ -1,153 +0,0 @@ -extension BSON -{ - @frozen public - struct List:Sendable - { - public - var output:BSON.Output - - /// Creates an empty list. - @inlinable public - init() - { - self.output = .init(preallocated: []) - } - @inlinable public - init(bytes:ArraySlice) - { - self.output = .init(preallocated: bytes) - } - } -} -extension BSON.List:BSON.BufferTraversable -{ - public - typealias Frame = BSON.DocumentFrame - - /// Stores the argument in ``bytes`` unchanged. Equivalent to ``init(bytes:)``. - /// - /// > Complexity: O(1) - @inlinable public - init(slicing bytes:ArraySlice) - { - self.init(bytes: bytes) - } - - /// The raw data backing this list. This collection *does not* include the trailing null - /// byte that appears after its inline elements list. - @inlinable public - var bytes:ArraySlice { self.output.destination } -} -extension BSON.List -{ - /// Indicates if this list contains no elements. - @inlinable public - var isEmpty:Bool { self.bytes.isEmpty } - - /// The length that would be encoded in this list’s prefixed header. - /// Equal to ``size``. - @inlinable public - var header:Int32 { .init(self.size) } - - /// The size of this list when encoded with its header and trailing - /// null byte. This *is* the same as the length encoded in the header - /// itself. - @inlinable public - var size:Int { 5 + self.bytes.count } -} -extension BSON.List:Equatable -{ - /// Performs an exact byte-wise comparison on two lists. - /// Does not parse or validate the operands. - @inlinable public static - func == (a:Self, b:Self) -> Bool { a.bytes.elementsEqual(b.bytes) } -} - -extension BSON.List -{ - /// Parses this list into key-value pairs in order, yielding each value to the - /// provided closure. Parsing a list is slightly faster than parsing a general - /// ``Document``, because this method ignores the document keys. - /// - /// This method does *not* perform any key validation. - /// - /// Unlike ``parse``, this method does not allocate storage for the parsed - /// elements. - /// - /// > Complexity: - /// O(*n*), where *n* is the size of this list’s backing storage. - @inlinable public - func parse(to decode:(_ element:BSON.AnyValue) throws -> ()) throws - { - var input:BSON.Input = .init(self.bytes) - while let code:UInt8 = input.next() - { - let type:BSON.AnyType = try .init(code: code) - try input.parse(through: 0x00) - try decode(try input.parse(variant: type)) - } - } - @inlinable public - func parse(_ transform:(_ element:BSON.AnyValue) throws -> T) throws -> [T] - { - var elements:[T] = [] - try self.parse - { - elements.append(try transform($0)) - } - return elements - } - - /// Splits this list’s inline key-value pairs into an array containing the - /// values only. Parsing a list is slightly faster than parsing a general - /// ``Document``, because this method ignores the document keys. - /// - /// This method does *not* perform any key validation. - /// - /// Calling this convenience method is the same as calling ``parse(to:)`` and - /// collecting the yielded elements in an array. - /// - /// > Complexity: - /// O(*n*), where *n* is the size of this list’s backing storage. - @inlinable public - func parse() throws -> [BSON.AnyValue] { try self.parse { $0 } } -} - -extension BSON.List:ExpressibleByArrayLiteral -{ - /// Creates a list-document containing the given elements. - @inlinable public - init(elements:some Sequence) - { - // we do need to precompute the ordinal keys, so we know the total length - // of the document. - let document:BSON.Document = .init(fields: elements.enumerated().map - { - (.init(index: $0.0), $0.1) - }) - self.init(bytes: document.bytes) - } - - @inlinable public - init(arrayLiteral:BSON.AnyValue...) - { - self.init(elements: arrayLiteral) - } -} - -extension BSON.List -{ - @available(*, deprecated, message: "BSON.List is already a BSON.List") - @inlinable public - init(_ bson:Self) - { - self = bson - } - - @available(*, deprecated, message: "BSON.List is already a BSON.List") - @inlinable public - init(bson:Self) - { - self = bson - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Max.swift b/Sources/BSONABI/Primitives/BSON.Max.swift deleted file mode 100644 index 1972e608..00000000 --- a/Sources/BSONABI/Primitives/BSON.Max.swift +++ /dev/null @@ -1,14 +0,0 @@ -extension BSON -{ - /// The MongoDB max-key. This type has a single state, and is - /// isomorphic to ``Void``. It is mainly used by the decoding - /// and encoding layers as an API landmark. - @frozen public - struct Max:Hashable, Equatable, Sendable - { - @inlinable public - init() - { - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Millisecond.swift b/Sources/BSONABI/Primitives/BSON.Millisecond.swift deleted file mode 100644 index ccba8c91..00000000 --- a/Sources/BSONABI/Primitives/BSON.Millisecond.swift +++ /dev/null @@ -1,18 +0,0 @@ -import UnixTime - -extension BSON -{ - @available(*, deprecated, renamed: "UnixMillisecond") - public - typealias Millisecond = UnixMillisecond -} -extension UnixMillisecond -{ - @available(*, unavailable, renamed: "init(index:)") - @inlinable public - init(_ index:Int64) { self.init(index: index) } - - @available(*, unavailable, renamed: "index") - @inlinable public - var value:Int64 { self.index } -} diff --git a/Sources/BSONABI/Primitives/BSON.Min.swift b/Sources/BSONABI/Primitives/BSON.Min.swift deleted file mode 100644 index 4a2fad09..00000000 --- a/Sources/BSONABI/Primitives/BSON.Min.swift +++ /dev/null @@ -1,14 +0,0 @@ -extension BSON -{ - /// The MongoDB min-key. This type has a single state, and is - /// isomorphic to ``Void``. It is mainly used by the decoding - /// and encoding layers as an API landmark. - @frozen public - struct Min:Hashable, Equatable, Sendable - { - @inlinable public - init() - { - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Null.swift b/Sources/BSONABI/Primitives/BSON.Null.swift deleted file mode 100644 index 0643d489..00000000 --- a/Sources/BSONABI/Primitives/BSON.Null.swift +++ /dev/null @@ -1,11 +0,0 @@ -extension BSON -{ - @frozen public - struct Null:Hashable, Equatable, Sendable - { - @inlinable public - init() - { - } - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Regex.OptionError.swift b/Sources/BSONABI/Primitives/BSON.Regex.OptionError.swift deleted file mode 100644 index 0af4fcec..00000000 --- a/Sources/BSONABI/Primitives/BSON.Regex.OptionError.swift +++ /dev/null @@ -1,24 +0,0 @@ -extension BSON.Regex -{ - /// A MongoDB regex matching options string contained an invalid unicode scalar. - @frozen public - struct OptionError:Equatable, Error - { - public - let codepoint:Unicode.Scalar - - @inlinable public - init(invalid codepoint:Unicode.Scalar) - { - self.codepoint = codepoint - } - } -} -extension BSON.Regex.OptionError:CustomStringConvertible -{ - public - var description:String - { - "invalid regex option '\(self.codepoint)'" - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Regex.Options.swift b/Sources/BSONABI/Primitives/BSON.Regex.Options.swift deleted file mode 100644 index 53633767..00000000 --- a/Sources/BSONABI/Primitives/BSON.Regex.Options.swift +++ /dev/null @@ -1,124 +0,0 @@ -extension BSON.Regex -{ - /// A MongoDB regex matching option. - @frozen public - enum Option:UInt8, CaseIterable, Hashable, Sendable - { - /// Enables case-insensitive matching. - case i = 0b000001 - /// Enables localization for `\w`, `\W`, etc. - case l = 0b000010 - /// Enables multiline matching. - case m = 0b000100 - /// Enables dotall mode. ([`'.'`]() matches everything.) - case s = 0b001000 - /// Enables unicode awareness for `\w`, `\W`, etc. - case u = 0b010000 - /// Enables verbose mode. - case x = 0b100000 - } - /// A set of MongoDB regex matching options. - @frozen public - struct Options:OptionSet, Sendable - { - public - let rawValue:UInt8 - - @inlinable public - init(rawValue:UInt8) - { - self.rawValue = rawValue - } - - public static let i:Self = .init(rawValue: Option.i.rawValue) - public static let l:Self = .init(rawValue: Option.l.rawValue) - public static let m:Self = .init(rawValue: Option.m.rawValue) - public static let s:Self = .init(rawValue: Option.s.rawValue) - public static let u:Self = .init(rawValue: Option.u.rawValue) - public static let x:Self = .init(rawValue: Option.x.rawValue) - } -} -extension BSON.Regex.Option -{ - @inlinable public - init?(_ scalar:Unicode.Scalar) - { - switch scalar - { - case "i": self = .i - case "l": self = .l - case "m": self = .m - case "s": self = .s - case "u": self = .u - case "x": self = .x - default: return nil - } - } - @inlinable public - var scalar:Unicode.Scalar - { - switch self - { - case .i: "i" - case .l: "l" - case .m: "m" - case .s: "s" - case .u: "u" - case .x: "x" - } - } - @inlinable public - var character:Character - { - .init(self.scalar) - } -} -extension BSON.Regex.Options -{ - /// Parses an option set from a MongoDB regex matching options string. - @inlinable public - init(parsing string:some StringProtocol) throws - { - var rawValue:UInt8 = 0 - for codepoint:Unicode.Scalar in string.unicodeScalars - { - if let option:BSON.Regex.Option = .init(codepoint) - { - rawValue |= option.rawValue - } - else - { - throw BSON.Regex.OptionError.init(invalid: codepoint) - } - } - self.init(rawValue: rawValue) - } -} - -extension BSON.Regex.Options -{ - /// The size of this option set, when encoded as a option string, including - /// its trailing null byte. - @inlinable public - var size:Int - { - self.rawValue.nonzeroBitCount + 1 - } -} -extension BSON.Regex.Options:CustomStringConvertible -{ - @inlinable public - func contains(option:BSON.Regex.Option) -> Bool - { - self.rawValue & option.rawValue != 0 - } - /// This option set, encoded in alphabetical order as a option string. - @inlinable public - var description:String - { - .init(BSON.Regex.Option.allCases.lazy.compactMap - { - self.contains(option: $0) ? $0.character : nil - }) - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Regex.swift b/Sources/BSONABI/Primitives/BSON.Regex.swift deleted file mode 100644 index 9785fd12..00000000 --- a/Sources/BSONABI/Primitives/BSON.Regex.swift +++ /dev/null @@ -1,34 +0,0 @@ -extension BSON -{ - /// A MongoDB regex. - @frozen public - struct Regex:Equatable, Sendable - { - public - var pattern:String - public - var options:Options - - @inlinable public - init(pattern:String, options:Options) - { - self.pattern = pattern - self.options = options - } - } -} -extension BSON.Regex -{ - @inlinable public - init(pattern:String, options:some StringProtocol) throws - { - self.init(pattern: pattern, options: try .init(parsing: options)) - } - - /// The size of this regex when encoded with interior and trailing null bytes. - @inlinable public - var size:Int - { - 1 + self.pattern.utf8.count + self.options.size - } -} diff --git a/Sources/BSONABI/Primitives/BSON.Timestamp.swift b/Sources/BSONABI/Primitives/BSON.Timestamp.swift deleted file mode 100644 index 657aba3c..00000000 --- a/Sources/BSONABI/Primitives/BSON.Timestamp.swift +++ /dev/null @@ -1,41 +0,0 @@ -extension BSON -{ - @frozen public - struct Timestamp:Equatable, Hashable, Sendable - { - public - var value:UInt64 - - @inlinable public - init(_ value:UInt64) - { - self.value = value - } - } -} -extension BSON.Timestamp -{ - @inlinable public static - var max:Self { .init(.max) } - - @inlinable public static - var min:Self { .init(.min) } -} -extension BSON.Timestamp:Comparable -{ - @inlinable public static - func < (a:Self, b:Self) -> Bool { a.value < b.value } -} -extension BSON.Timestamp:ExpressibleByIntegerLiteral -{ - @inlinable public - init(integerLiteral:UInt64) { self.init(integerLiteral) } -} -extension BSON.Timestamp:CustomStringConvertible -{ - public - var description:String - { - "\(self.value >> 32)+\(self.value & 0x0000_0000_ffff_ffff)" - } -} diff --git a/Sources/BSONABI/README.md b/Sources/BSONABI/README.md deleted file mode 100644 index d2dc1b5f..00000000 --- a/Sources/BSONABI/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# ``/BSONABI`` - -Models the BSON type system and the binary interface of the BSON serialization format. - -External users should avoid importing this module directly. Instead, import ``/BSON``. - -## Topics - -### Type system - -- ``BSON.AnyValue`` -- ``BSON.AnyType`` - -### Primitive types - -- ``BSON.Min`` -- ``BSON.Max`` -- ``BSON.Identifier`` -- ``BSON.Decimal128`` -- ``BSON.Regex`` -- ``UnixMillisecond`` - -### String-like types - -- ``BSON.BinaryView`` -- ``BSON.UTF8View`` - -### Container types - -- ``BSON.List`` -- ``BSON.Document`` - -### Container fields - -- ``BSON.Key`` -- ``BSON.FieldEncoder`` - -### Binary interface - -- ``BSON.BufferTraversable`` -- ``BSON.BufferFrame`` - -### Binary frame types - -- ``BSON.BinaryFrame`` -- ``BSON.DocumentFrame`` -- ``BSON.UTF8Frame`` - -### Parsing and decoding - -This module only implements the basic infrastructure for BSON decoding. Most of the public decoding interface is in ``BSONDecoding``. - -- ``BSON.Decoder`` -- ``BSON.Input`` -- ``BSON.TypeError`` -- ``BSON.TypecastError`` - -### Serialization and encoding - -This module only implements the basic infrastructure for BSON encoding. Most of the public encoding interface is in ``BSONEncoding``. - -- ``BSON.Encoder`` -- ``BSON.Output`` diff --git a/Sources/BSONABI/Views/BSON.BinaryFrame.swift b/Sources/BSONABI/Views/BSON.BinaryFrame.swift deleted file mode 100644 index 8f1034d1..00000000 --- a/Sources/BSONABI/Views/BSON.BinaryFrame.swift +++ /dev/null @@ -1,30 +0,0 @@ -extension BSON -{ - /// Specifies the interpretation of a length header attached to a ``BSON.AnyType/binary`` - /// array. - @frozen public - enum BinaryFrame - { - case binary - } -} -extension BSON.BinaryFrame:BSON.BufferFrame -{ - @inlinable public - var type:BSON.AnyType - { - switch self - { - case .binary: .binary - } - } - - /// A binary array never has any trailing bytes when serialized. - @inlinable public static - var trailer:UInt8? { nil } - - /// A binary array header starts its count after skipping the interceding - /// ``BinaryView/subtype`` byte. - @inlinable public static - var skipped:Int { 1 } -} diff --git a/Sources/BSONABI/Views/BSON.BinarySubtype.swift b/Sources/BSONABI/Views/BSON.BinarySubtype.swift deleted file mode 100644 index 404790d6..00000000 --- a/Sources/BSONABI/Views/BSON.BinarySubtype.swift +++ /dev/null @@ -1,61 +0,0 @@ -extension BSON -{ - /// A BSON binary metatype. This type’s public API performs canonicalization - /// and therefore instances of this type are safe to compare. - @frozen public - struct BinarySubtype:Hashable, RawRepresentable, Sendable - { - @inlinable public static var generic:Self { .init(unchecked: 0x00) } - @inlinable public static var function:Self { .init(unchecked: 0x01) } - @inlinable public static var uuid:Self { .init(unchecked: 0x04) } - @inlinable public static var md5:Self { .init(unchecked: 0x05) } - @inlinable public static var encrypted:Self { .init(unchecked: 0x06) } - @inlinable public static var compressed:Self { .init(unchecked: 0x07) } - - public - let rawValue:UInt8 - - /// Initializes a binary subtype from an unchecked subtype code. - /// Performs no normalization. - /// - /// Most users should not need to call this initializer; prefer - /// one of ``init(rawValue:)``, `custom(code:)`, or one of the - /// known types: ``generic``, ``function``, ``uuid``, ``md5``, - /// ``encrypted``, or ``compressed``. - @inlinable public - init(unchecked code:UInt8) - { - self.rawValue = code - } - /// Detects and normalizes a binary subtype from the given - /// raw subtype code. Deprecated encodings (`0x02` and `0x03`) - /// will be normalized to their canonical encoding. - /// - /// This initializer fails if `rawValue` is a reserved bit pattern. - @inlinable public - init?(rawValue:UInt8) - { - switch rawValue - { - case 0x00, 0x02: self.rawValue = 0x00 - case 0x01: self.rawValue = 0x01 - case 0x03, 0x04: self.rawValue = 0x04 - case 0x05: self.rawValue = 0x05 - case 0x06: self.rawValue = 0x06 - case 0x07: self.rawValue = 0x07 - case 0x80 ... 0xFF: self.rawValue = rawValue - default: return nil - } - } - /// Returns a custom binary subtype. Traps if `code` is less than `0x80`. - @inlinable public static - func custom(code:UInt8) -> Self - { - if code < 0x80 - { - fatalError("custom code cannot be less than 0x80") - } - return .init(unchecked: code) - } - } -} diff --git a/Sources/BSONABI/Views/BSON.BinarySubtypeError.swift b/Sources/BSONABI/Views/BSON.BinarySubtypeError.swift deleted file mode 100644 index 49609653..00000000 --- a/Sources/BSONABI/Views/BSON.BinarySubtypeError.swift +++ /dev/null @@ -1,24 +0,0 @@ -extension BSON -{ - /// The subtype byte of a binary array matched a reserved bit pattern. - @frozen public - struct BinarySubtypeError:Equatable, Error - { - public - let code:UInt8 - - @inlinable public - init(invalid code:UInt8) - { - self.code = code - } - } -} -extension BSON.BinarySubtypeError:CustomStringConvertible -{ - public - var description:String - { - "invalid binary subtype code (\(self.code))" - } -} diff --git a/Sources/BSONABI/Views/BSON.BinaryView.swift b/Sources/BSONABI/Views/BSON.BinaryView.swift deleted file mode 100644 index 96f74aa5..00000000 --- a/Sources/BSONABI/Views/BSON.BinaryView.swift +++ /dev/null @@ -1,96 +0,0 @@ -extension BSON -{ - /// A BSON binary array. - @frozen public - struct BinaryView where Bytes:RandomAccessCollection - { - /// The contents of this binary array. This collection does *not* - /// include the leading subtype byte. - public - let bytes:Bytes - /// The subtype of this binary array. - public - let subtype:BinarySubtype - - @inlinable public - init(subtype:BinarySubtype, bytes:Bytes) - { - self.subtype = subtype - self.bytes = bytes - } - } -} -extension BSON.BinaryView:Sendable where Bytes:Sendable -{ -} -extension BSON.BinaryView:Equatable -{ - /// Performs an exact byte-wise comparison on two binary arrays. - /// The subtypes must match as well. - @inlinable public static - func == (lhs:Self, rhs:BSON.BinaryView>) -> Bool - { - lhs.subtype == rhs.subtype && - lhs.bytes.elementsEqual(rhs.bytes) - } -} -extension BSON.BinaryView>:BSON.BufferTraversable -{ - public - typealias Frame = BSON.BinaryFrame - - /// Removes the first element of the argument, attempts to cast it to a - /// ``BinarySubtype``, and stores the remainder in ``bytes``. - /// - /// If the subtype is the deprecated generic subtype (code [`0x02`]()), - /// the inner length header will be stripped from ``bytes`` and ignored. - /// - /// > Complexity: O(1) - @inlinable public - init(slicing bytes:ArraySlice) throws - { - guard let code:UInt8 = bytes.first - else - { - throw BSON.BinaryViewError.init(expected: .subtype) - } - guard let subtype:BSON.BinarySubtype = .init(rawValue: code) - else - { - throw BSON.BinarySubtypeError.init(invalid: code) - } - - let start:Int = bytes.index(after: bytes.startIndex) - if code != 0x02 - { - self.init(subtype: subtype, bytes: bytes[start...]) - } - // special handling for legacy binary format 0x02 - else if let start:Int = bytes.index(start, offsetBy: 4, - limitedBy: bytes.endIndex) - { - self.init(subtype: subtype, bytes: bytes.suffix(from: start)) - } - else - { - throw BSON.BinaryViewError.init(expected: .subheader) - } - } -} -extension BSON.BinaryView -{ - /// The length that would be encoded in this binary array’s prefixed header. - /// Equal to [`self.bytes.count`](). - @inlinable public - var header:Int32 - { - .init(self.bytes.count) - } - /// The size of this binary array when encoded with its header. - /// This is *not* the length encoded in the header itself. - @inlinable public - var size:Int - { - 5 + self.bytes.count - } -} diff --git a/Sources/BSONABI/Views/BSON.BinaryViewError.Expectation.swift b/Sources/BSONABI/Views/BSON.BinaryViewError.Expectation.swift deleted file mode 100644 index 1895afe7..00000000 --- a/Sources/BSONABI/Views/BSON.BinaryViewError.Expectation.swift +++ /dev/null @@ -1,25 +0,0 @@ -extension BSON.BinaryViewError -{ - @frozen public - enum Expectation:Equatable, Sendable - { - /// The input should have yielded a subtype byte. - case subtype - /// The input should have yielded a legacy subheader. - case subheader - } -} -extension BSON.BinaryViewError.Expectation:CustomStringConvertible -{ - public - var description:String - { - switch self - { - case .subtype: - "subtype (1 byte)" - case .subheader: - "subheader (4 bytes)" - } - } -} diff --git a/Sources/BSONABI/Views/BSON.BinaryViewError.swift b/Sources/BSONABI/Views/BSON.BinaryViewError.swift deleted file mode 100644 index cb4adb3d..00000000 --- a/Sources/BSONABI/Views/BSON.BinaryViewError.swift +++ /dev/null @@ -1,25 +0,0 @@ -extension BSON -{ - /// A binary view was sliced from a malformed storage buffer. - @frozen public - struct BinaryViewError:Equatable, Error - { - /// What the input should have yielded. - public - let expected:Expectation - - @inlinable public - init(expected:Expectation) - { - self.expected = expected - } - } -} -extension BSON.BinaryViewError:CustomStringConvertible -{ - public - var description:String - { - "expected \(self.expected)" - } -} diff --git a/Sources/BSONABI/Views/BSON.DocumentFrame.swift b/Sources/BSONABI/Views/BSON.DocumentFrame.swift deleted file mode 100644 index 40a8f7a4..00000000 --- a/Sources/BSONABI/Views/BSON.DocumentFrame.swift +++ /dev/null @@ -1,32 +0,0 @@ -extension BSON -{ - /// Specifies the interpretation of a length header attached to a ``BSON.AnyType/document``, - /// or a ``BSON.AnyType/list`` document. - @frozen public - enum DocumentFrame - { - case document - case list - } -} -extension BSON.DocumentFrame:BSON.BufferFrame -{ - @inlinable public - var type:BSON.AnyType - { - switch self - { - case .document: .document - case .list: .list - } - } - - /// A document always includes a trailing null byte when serialized. - @inlinable public static - var trailer:UInt8? { 0x00 } - - /// A document’s length header counts its own length. In other words, - /// it skips negative 4 bytes. - @inlinable public static - var skipped:Int { -4 } -} diff --git a/Sources/BSONABI/Views/BSON.UTF8Frame.swift b/Sources/BSONABI/Views/BSON.UTF8Frame.swift deleted file mode 100644 index e32d0a8d..00000000 --- a/Sources/BSONABI/Views/BSON.UTF8Frame.swift +++ /dev/null @@ -1,29 +0,0 @@ -extension BSON -{ - /// Specifies the interpretation of a length header attached to UTF-8 ``string``. - @frozen public - enum UTF8Frame - { - case string - case javascript - } -} -extension BSON.UTF8Frame:BSON.BufferFrame -{ - @inlinable public - var type:BSON.AnyType - { - switch self - { - case .string: .string - case .javascript: .javascript - } - } - - /// A UTF-8 string’s length header does not count its own length. - @inlinable public static - var skipped:Int { 0 } - /// A UTF-8 string always includes a trailing null byte when serialized. - @inlinable public static - var trailer:UInt8? { 0x00 } -} diff --git a/Sources/BSONABI/Views/BSON.UTF8View.swift b/Sources/BSONABI/Views/BSON.UTF8View.swift deleted file mode 100644 index 2c9c9f2e..00000000 --- a/Sources/BSONABI/Views/BSON.UTF8View.swift +++ /dev/null @@ -1,153 +0,0 @@ -extension BSON -{ - /// A BSON UTF-8 string. This string is allowed to contain null bytes. - /// - /// This type can wrap potentially-invalid UTF-8 data, therefore it - /// is not backed by an instance of ``String``. Moreover, it (and not ``String``) - /// is the payload of ``BSON/AnyValue.string(_:)`` to ensure that long string - /// fields can be traversed in constant time. - /// - /// To convert a UTF-8 string to a native Swift ``String`` (repairing invalid UTF-8), - /// use the ``description`` property. - @frozen public - struct UTF8View where Bytes:BidirectionalCollection - { - /// The UTF-8 code units backing this string. This collection does *not* - /// include the trailing null byte that typically appears when this value - /// occurs inline in a document. - public - let bytes:Bytes - - @inlinable public - init(bytes:Bytes) - { - self.bytes = bytes - } - } -} -extension BSON.UTF8View:Sendable where Bytes:Sendable -{ -} -extension BSON.UTF8View>:BSON.BufferTraversable -{ - public - typealias Frame = BSON.UTF8Frame - - /// Stores the argument in ``bytes`` unchanged. Equivalent to ``init(bytes:)``. - /// - /// > Complexity: O(1) - @inlinable public - init(slicing bytes:Bytes) throws - { - self.init(bytes: bytes) - } -} -extension BSON.UTF8View:Equatable -{ - /// Performs a unicode-aware string comparison on two UTF-8 strings. - @inlinable public static - func == (lhs:Self, rhs:BSON.UTF8View>) -> Bool - { - lhs.description == rhs.description - } -} -extension BSON.UTF8View where Bytes:RangeReplaceableCollection -{ - /// Creates a BSON UTF-8 string by copying the UTF-8 code units of - /// the given string to dedicated backing storage. - /// When possible, prefer using a specialization of this type where - /// `Bytes` is `String.UTF8View` or `Substring.UTF8View`, because - /// instances of those specializations can be constructed as - /// copy-less collection views. - /// - /// > Complexity: - /// O(*n*), where *n* is the length of the string. - @inlinable public - init(from string:some StringProtocol) - { - self.init(bytes: .init(string.utf8)) - } -} -extension BSON.UTF8View:ExpressibleByStringLiteral, - ExpressibleByExtendedGraphemeClusterLiteral, - ExpressibleByUnicodeScalarLiteral -{ - @inlinable public - init(stringLiteral:String) - { - self.init(stringLiteral) - } - - /// Creates a BSON UTF-8 string backed by a ``String.UTF8View``, making - /// the base string contiguous, if it is not already. - /// - /// > Complexity: - /// O(1) if the string is already a contiguous UTF-8 string; - /// otherwise O(*n*), where *n* is the length of the string. - @inlinable public - init(_ string:String) - { - var string:String = string - string.makeContiguousUTF8() - self.init(bytes: string.utf8) - } -} -extension BSON.UTF8View -{ - /// Creates a BSON UTF-8 string backed by a ``Substring.UTF8View``, making - /// the base substring contiguous, if it is not already. - /// - /// > Complexity: - /// O(1) if the substring is already a contiguous UTF-8 substring; - /// otherwise O(*n*), where *n* is the length of the substring. - @inlinable public - init(_ string:Substring) - { - var string:Substring = string - string.makeContiguousUTF8() - self.init(bytes: string.utf8) - } -} -extension BSON.UTF8View> -{ - /// Creates a BSON UTF-8 string backed by a `[UInt8]` array slice, by copying - /// the UTF-8 code units stored in the given static string. - /// - /// > Complexity: - /// O(*n*), where *n* is the length of the string. - @inlinable public - init(_ string:StaticString) - { - self.init(bytes: string.withUTF8Buffer(ArraySlice.init(_:))) - } -} - -extension BSON.UTF8View:CustomStringConvertible -{ - /// Copies and validates the backing storage of the given UTF-8 string to a - /// native Swift string, repairing invalid code units if needed. - /// - /// > Complexity: O(*n*), where *n* is the length of the string. - @inlinable public - var description:String - { - .init(decoding: self.bytes, as: Unicode.UTF8.self) - } -} -extension BSON.UTF8View -{ - /// The length that would be encoded in this string’s prefixed header. - /// Equal to [`self.slice.count + 1`](). - @inlinable public - var header:Int32 - { - Int32.init(self.bytes.count) + 1 - } - /// The size of this string when encoded with its header and trailing null byte. - /// This is *not* the length encoded in the header itself. - @inlinable public - var size:Int - { - 5 + self.bytes.count - } -} diff --git a/Sources/BSONDecoding/Array (ext).swift b/Sources/BSONDecoding/Array (ext).swift deleted file mode 100644 index 4295fcc5..00000000 --- a/Sources/BSONDecoding/Array (ext).swift +++ /dev/null @@ -1,17 +0,0 @@ -extension Array:BSONDecodable where Element:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(bson: consume bson)) - } - @inlinable public - init(bson:BSON.List) throws - { - self.init() - try bson.parse - { - self.append(try $0.decode(to: Element.self)) - } - } -} diff --git a/Sources/BSONDecoding/BSON.FieldDecoder.swift b/Sources/BSONDecoding/BSON.FieldDecoder.swift deleted file mode 100644 index 754c2517..00000000 --- a/Sources/BSONDecoding/BSON.FieldDecoder.swift +++ /dev/null @@ -1,36 +0,0 @@ -extension BSON -{ - @frozen public - struct FieldDecoder where Key:Sendable - { - public - let key:Key - public - let value:BSON.AnyValue - - @inlinable public - init(key:Key, value:BSON.AnyValue) - { - self.key = key - self.value = value - } - } -} -extension BSON.FieldDecoder:BSON.TraceableDecoder -{ - /// Decodes the value of this field with the given decoder. - /// Throws a ``BSON/DecodingError`` wrapping the underlying - /// error if decoding fails. - @inlinable public - func decode(with decode:(BSON.AnyValue) throws -> T) throws -> T - { - do - { - return try decode(self.value) - } - catch let error - { - throw BSON.DecodingError.init(error, in: self.key) - } - } -} diff --git a/Sources/BSONDecoding/BSON.OptionalDecoder.swift b/Sources/BSONDecoding/BSON.OptionalDecoder.swift deleted file mode 100644 index 30acdd95..00000000 --- a/Sources/BSONDecoding/BSON.OptionalDecoder.swift +++ /dev/null @@ -1,77 +0,0 @@ -extension BSON -{ - /// A field that may or may not exist in a document. This type is - /// the return value of ``Dictionary``’s non-optional subscript, and - /// is useful for obtaining structured diagnostics for “key-not-found” - /// scenarios. - @frozen public - struct OptionalDecoder where Key:Sendable - { - public - let key:Key - public - let value:BSON.AnyValue? - - @inlinable public - init(key:Key, value:BSON.AnyValue?) - { - self.key = key - self.value = value - } - } -} -extension BSON.OptionalDecoder -{ - @inlinable public static - func ?? (lhs:Self, rhs:@autoclosure () -> Self) -> Self - { - if case nil = lhs.value - { - rhs() - } - else - { - lhs - } - } -} -extension BSON.OptionalDecoder -{ - /// Gets the value of this key, throwing a ``BSON.DocumentKeyError`` - /// if it is nil. This is a distinct condition from an explicit - /// ``BSON/AnyValue/null`` value, which will be returned without throwing an error. - @inlinable public - func decode() throws -> BSON.AnyValue - { - if let value:BSON.AnyValue = self.value - { - return value - } - else - { - throw BSON.DocumentKeyError.undefined(self.key) - } - } -} -extension BSON.OptionalDecoder:BSON.TraceableDecoder -{ - /// Decodes the value of this implicit field with the given decoder, throwing a - /// ``BSON.DocumentKeyError`` if it does not exist. Throws a - /// ``BSON.DecodingError`` wrapping the underlying error if decoding fails. - @inlinable public - func decode(with decode:(BSON.AnyValue) throws -> T) throws -> T - { - // we cannot *quite* shove this into the `do` block, because we - // do not want to throw a ``DecodingError`` just because the key - // was not found. - let value:BSON.AnyValue = try self.decode() - do - { - return try decode(value) - } - catch let error - { - throw BSON.DecodingError.init(error, in: key) - } - } -} diff --git a/Sources/BSONDecoding/BSON.TraceableDecoder.swift b/Sources/BSONDecoding/BSON.TraceableDecoder.swift deleted file mode 100644 index fa2b6652..00000000 --- a/Sources/BSONDecoding/BSON.TraceableDecoder.swift +++ /dev/null @@ -1,44 +0,0 @@ -extension BSON -{ - /// A type that represents a scope for decoding operations. - public - protocol TraceableDecoder - { - /// Attempts to load a BSON variant value and passes it to the given - /// closure, returns its result. If decoding fails, the implementation - /// should annotate the error with appropriate context and re-throw it. - func decode(with decode:(AnyValue) throws -> T) throws -> T - } -} -extension BSON.TraceableDecoder -{ - @inlinable public - func decode(using _:CodingKey.Type = CodingKey.self, - with decode:(BSON.DocumentDecoder) throws -> T) throws -> T - { - try self.decode { try decode(try .init(parsing: $0)) } - } - @inlinable public - func decode(with decode:(BSON.DocumentDecoder) throws -> T) throws -> T - { - try self.decode { try decode(try .init(parsing: $0)) } - } - @inlinable public - func decode(with decode:(BSON.ListDecoder) throws -> T) throws -> T - { - try self.decode { try decode(try .init(parsing: $0)) } - } - - @inlinable public - func decode(as _:Decodable.Type, - with decode:(Decodable) throws -> T) throws -> T where Decodable:BSONDecodable - { - try self.decode { try decode(try .init(bson: $0)) } - } - @inlinable public - func decode( - to _:Decodable.Type = Decodable.self) throws -> Decodable where Decodable:BSONDecodable - { - try self.decode(with: Decodable.init(bson:)) - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONArrayDecodable.swift b/Sources/BSONDecoding/Decodability/BSONArrayDecodable.swift deleted file mode 100644 index b5008f66..00000000 --- a/Sources/BSONDecoding/Decodability/BSONArrayDecodable.swift +++ /dev/null @@ -1,17 +0,0 @@ -public -protocol BSONArrayDecodable:BSONBinaryDecodable -{ - associatedtype CodingElement //:_Trivial - - /// Initializes an instance of this type from the given binary array, whose shape has been - /// pre-validated to be a multiple of the ``CodingElement`` size. - init(from array:borrowing BSON.BinaryArray) throws -} -extension BSONArrayDecodable -{ - @inlinable public - init(bson:BSON.BinaryDecoder) throws - { - try self.init(from: try .init(bson: bson)) - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONBinaryDecodable.swift b/Sources/BSONDecoding/Decodability/BSONBinaryDecodable.swift deleted file mode 100644 index f04c8ce8..00000000 --- a/Sources/BSONDecoding/Decodability/BSONBinaryDecodable.swift +++ /dev/null @@ -1,18 +0,0 @@ -/// A type that can be decoded from a BSON binary array. -public -protocol BSONBinaryDecodable:BSONDecodable -{ - /// Initializes an instance of this type from the given binary array, - /// validating the subtype if the conforming type performs type checking. - init(bson:BSON.BinaryDecoder) throws -} -extension BSONBinaryDecodable -{ - /// Attempts to cast the given variant value to a binary array, and then - /// delegates to this type’s ``init(bson:) [5T44S]`` witness. - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(parsing: bson)) - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONDecodable.swift b/Sources/BSONDecoding/Decodability/BSONDecodable.swift deleted file mode 100644 index b8d7694e..00000000 --- a/Sources/BSONDecoding/Decodability/BSONDecodable.swift +++ /dev/null @@ -1,53 +0,0 @@ -import BSONABI - -/// A type that can be decoded from a BSON variant value backed by -/// some type of storage not particular to the decoded type. -public -protocol BSONDecodable -{ - /// Attempts to cast a BSON variant backed by some storage type to an - /// instance of this type. The implementation can copy the contents - /// of the backing storage if needed. - init(bson:BSON.AnyValue) throws -} - -extension BSONDecodable where Self:BSONRepresentable, BSONRepresentation:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self.init(try .init(bson: bson)) - } -} -extension BSONDecodable where Self:RawRepresentable, RawValue:BSONDecodable & Sendable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - let rawValue:RawValue = try .init(bson: bson) - if let value:Self = .init(rawValue: rawValue) - { - self = value - } - else - { - throw BSON.ValueError.init(invalid: rawValue) - } - } -} -extension BSONDecodable where Self:FixedWidthInteger -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { try $0.as(Self.self) } - } -} -extension BSONDecodable where Self:BinaryFloatingPoint -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONDocumentDecodable.swift b/Sources/BSONDecoding/Decodability/BSONDocumentDecodable.swift deleted file mode 100644 index d69aa47f..00000000 --- a/Sources/BSONDecoding/Decodability/BSONDocumentDecodable.swift +++ /dev/null @@ -1,22 +0,0 @@ -/// A type that can be decoded from a BSON dictionary-decoder. -public -protocol BSONDocumentDecodable:BSONDecodable -{ - associatedtype CodingKey:RawRepresentable & Hashable & Sendable = BSON.Key - - init(bson:BSON.DocumentDecoder) throws -} -extension BSONDocumentDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(parsing: bson)) - } - - @inlinable public - init(bson:BSON.Document) throws - { - try self.init(bson: try .init(parsing: bson)) - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONListDecodable.swift b/Sources/BSONDecoding/Decodability/BSONListDecodable.swift deleted file mode 100644 index f067bfed..00000000 --- a/Sources/BSONDecoding/Decodability/BSONListDecodable.swift +++ /dev/null @@ -1,22 +0,0 @@ -/// A type that can be decoded from a BSON list-decoder. You should only conform to this -/// protocol if you need random-access decoding. Many arraylike data structures are -/// more-efficiently decoded from a ``BSON.List`` at the ``BSONDecodable`` level. -public -protocol BSONListDecodable:BSONDecodable -{ - init(bson:BSON.ListDecoder) throws -} -extension BSONListDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(parsing: bson)) - } - - @inlinable public - init(bson:BSON.List) throws - { - try self.init(bson: try .init(parsing: bson)) - } -} diff --git a/Sources/BSONDecoding/Decodability/BSONStringDecodable.swift b/Sources/BSONDecoding/Decodability/BSONStringDecodable.swift deleted file mode 100644 index 3989708d..00000000 --- a/Sources/BSONDecoding/Decodability/BSONStringDecodable.swift +++ /dev/null @@ -1,44 +0,0 @@ -/// A type that can be decoded from a BSON UTF-8 string. Javascript sources -/// count as UTF-8 strings, from the perspective of this protocol. This protocol -/// exists to allow types that also conform to ``LosslessStringConvertible`` -/// to opt-in to automatic ``BSONDecodable`` conformance as well. -public -protocol BSONStringDecodable:BSONDecodable -{ - /// Initializes an instance of this type from the given UTF-8 string. - init(bson:BSON.UTF8View>) throws -} -extension BSONStringDecodable -{ - /// Attempts to cast the given variant value to a string, and then - /// delegates to this type’s ``init(bson:) [3WSG]`` witness. - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(bson: bson)) - } -} -extension BSONStringDecodable where Self:LosslessStringConvertible -{ - /// Attempts to cast the given variant value to a string, and then - /// delegates to this type’s ``LosslessStringConvertible/init(_:)`` witness. - /// - /// This default implementation is provided on an extension on a - /// dedicated protocol rather than an extension on ``BSONDecodable`` - /// itself to prevent unexpected behavior for types (such as ``Double``) - /// who implement ``LosslessStringConvertible``, but expect to be - /// decoded from a variant value that is not a string. - @inlinable public - init(bson:BSON.UTF8View>) throws - { - let string:String = .init(bson: bson) - if let value:Self = .init(string) - { - self = value - } - else - { - throw BSON.ValueError.init(invalid: string) - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.BinaryArray.swift b/Sources/BSONDecoding/Decoding/BSON.BinaryArray.swift deleted file mode 100644 index 8470fffc..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.BinaryArray.swift +++ /dev/null @@ -1,53 +0,0 @@ -extension BSON -{ - /// A `BinaryArray` is a typed view of an ``ArraySlice`` as a densly-packed buffer of - /// trivial `Element`s. It’s a good idea to use something unpretentious like a tuple of - /// fixed-width integers for the `Element` type, to avoid unexpected padding behavior. - /// - /// In any large MongoDB deployment, you should assume that your schema will be loaded and - /// saved from machines with different endianness. - @frozen public - struct BinaryArray - { - public - let bytes:ArraySlice - public - let count:Int - - @inlinable - init(bytes:ArraySlice, count:Int) - { - self.bytes = bytes - self.count = count - } - } -} -extension BSON.BinaryArray:BSONBinaryDecodable -{ - @inlinable public - init(bson:BSON.BinaryDecoder) throws - { - self.init(bytes: bson.bytes, - count: try bson.shape.expect(multipleOf: MemoryLayout.size)) - } -} -extension BSON.BinaryArray:RandomAccessCollection -{ - @inlinable public - var startIndex:Int { 0 } - - @inlinable public - var endIndex:Int { self.count } - - @inlinable public - subscript(position:Int) -> Element - { - precondition(self.indices ~= position, "Index out of bounds") - - return self.bytes.withUnsafeBytes - { - $0.loadUnaligned(fromByteOffset: position * MemoryLayout.size, - as: Element.self) - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.BinaryDecoder.swift b/Sources/BSONDecoding/Decoding/BSON.BinaryDecoder.swift deleted file mode 100644 index 25aca940..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.BinaryDecoder.swift +++ /dev/null @@ -1,36 +0,0 @@ -extension BSON -{ - @frozen public - struct BinaryDecoder - { - @usableFromInline - let view:BSON.BinaryView> - - @inlinable - init(view:BSON.BinaryView>) - { - self.view = view - } - } -} -extension BSON.BinaryDecoder:BSON.Decoder -{ - /// Attempts to unwrap a binary array from the given variant. Despite the name, this - /// initializer performs no actual parsing. - @inlinable public - init(parsing bson:borrowing BSON.AnyValue) throws - { - self.init(view: try .init(bson: copy bson)) - } -} -extension BSON.BinaryDecoder -{ - @inlinable public - var bytes:ArraySlice { self.view.bytes } - - @inlinable public - var shape:BSON.Shape { .init(length: self.view.bytes.count) } - - @inlinable public - var subtype:BSON.BinarySubtype { self.view.subtype } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.BinarySubtype (ext).swift b/Sources/BSONDecoding/Decoding/BSON.BinarySubtype (ext).swift deleted file mode 100644 index 397764f3..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.BinarySubtype (ext).swift +++ /dev/null @@ -1,13 +0,0 @@ -extension BSON.BinarySubtype -{ - /// Throws a ``BinaryTypecastError`` if this subtype doesn’t match the specified - /// subtype. - @inlinable public - func expect(_ subtype:Self) throws - { - if self != subtype - { - throw BSON.BinaryTypecastError.init(invalid: self, expected: subtype) - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.BinaryTypecastError.swift b/Sources/BSONDecoding/Decoding/BSON.BinaryTypecastError.swift deleted file mode 100644 index 0b197494..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.BinaryTypecastError.swift +++ /dev/null @@ -1,30 +0,0 @@ -extension BSON -{ - /// A list had an invalid number of elements. - @frozen public - struct BinaryTypecastError:Equatable, Error - { - public - let subtype:BinarySubtype - public - let expected:BinarySubtype? - - @inlinable public - init(invalid:BinarySubtype, expected:BinarySubtype? = nil) - { - self.subtype = invalid - self.expected = expected - } - } -} -extension BSON.BinaryTypecastError:CustomStringConvertible -{ - public - var description:String - { - self.expected.map - { - "invalid subtype '\(subtype)', expected '\($0)'" - } ?? "invalid subtype '\(subtype)'" - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.BinaryView (ext).swift b/Sources/BSONDecoding/Decoding/BSON.BinaryView (ext).swift deleted file mode 100644 index 23f04153..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.BinaryView (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.BinaryView>:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast(with: \.binary) - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.DecodingError.swift b/Sources/BSONDecoding/Decoding/BSON.DecodingError.swift deleted file mode 100644 index 90101b99..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.DecodingError.swift +++ /dev/null @@ -1,46 +0,0 @@ -import TraceableErrors - -extension BSON -{ - /// An error occurred while decoding a document field. - @frozen public - struct DecodingError:Error where Location:Sendable - { - /// The location (key or index) where the error occurred. - public - let location:Location - /// The underlying error that occurred. - public - let underlying:any Error - - @inlinable public - init(_ underlying:any Error, in location:Location) - { - self.location = location - self.underlying = underlying - } - } -} -extension BSON.DecodingError:Equatable where Location:Equatable -{ - /// Compares the ``location`` properties and the ``underlying`` - /// errors of the operands for equality, returning `true` - /// if they are equal. Always returns `false` if (any of) - /// the underlying ``Error`` existentials are not ``Equatable``. - public static - func == (lhs:Self, rhs:Self) -> Bool - { - lhs.location == rhs.location && - lhs.underlying == rhs.underlying - } -} -extension BSON.DecodingError:TraceableError -{ - /// Returns a single note that says - /// [`"while decoding value for field '_'"`](). - public - var notes:[String] - { - ["while decoding value for field '\(self.location)'"] - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.Document (ext).swift b/Sources/BSONDecoding/Decoding/BSON.Document (ext).swift deleted file mode 100644 index 47d5c6ae..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.Document (ext).swift +++ /dev/null @@ -1,21 +0,0 @@ -extension BSON.Document:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast(with: \.document) - } -} -extension BSON.Document -{ - /// Decorates the ``BSON.AnyValue``-yielding overload of this method with one that - /// yields the key-value pairs as fields. - @inlinable public - func parse(to decode:(_ field:BSON.FieldDecoder) throws -> ()) throws - { - try self.parse - { - try decode(.init(key: $0, value: $1)) - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.Iterator.swift b/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.Iterator.swift deleted file mode 100644 index 2feb466c..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.Iterator.swift +++ /dev/null @@ -1,23 +0,0 @@ -extension BSON.DocumentDecoder -{ - @frozen public - struct Iterator - { - @usableFromInline internal - var base:Dictionary.Iterator - - @inlinable internal - init(base:Dictionary.Iterator) - { - self.base = base - } - } -} -extension BSON.DocumentDecoder.Iterator:IteratorProtocol -{ - @inlinable public mutating - func next() -> BSON.FieldDecoder? - { - self.base.next().map { .init(key: $0.key, value: $0.value) } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.swift b/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.swift deleted file mode 100644 index 380b687e..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.DocumentDecoder.swift +++ /dev/null @@ -1,126 +0,0 @@ -extension BSON -{ - /// A thin wrapper around a native Swift dictionary providing an efficient decoding - /// interface for a ``BSON/Document``. - @frozen public - struct DocumentDecoder - where CodingKey:RawRepresentable, - CodingKey:Hashable, - CodingKey:Sendable - { - @usableFromInline - var index:[CodingKey: BSON.AnyValue] - - @inlinable public - init(_ index:[CodingKey: BSON.AnyValue] = [:]) - { - self.index = index - } - } -} -extension BSON.DocumentDecoder:BSON.Decoder -{ - /// Attempts to load a document decoder from the given variant. - /// - /// - Returns: - /// A document decoder derived from the payload of this variant if it matches - /// ``AnyValue/document(_:) [case]`` **or** ``AnyValue/list(_:) [case]``, nil otherwise. - @inlinable public - init(parsing bson:borrowing BSON.AnyValue) throws - { - try self.init(parsing: try .init(bson: copy bson)) - } -} -extension BSON.DocumentDecoder -{ - /// Attempts to create a decoder with typed coding keys from this document. - /// - /// This function will ignore fields whose keys do not correspond to valid - /// instances of `CodingKey`. It will throw a ``DocumentKeyError`` if more - /// than one non-ignored document field contains the same key. - /// - /// If `CodingKey` is ``Key``, this function will never ignore fields. - /// - /// Key duplication can interact with unicode normalization in unexpected - /// ways. Because BSON is defined in UTF-8, other BSON encoders may not align - /// with the behavior of ``String.==(_:_:) [9812Z]``, since that operator - /// compares grapheme clusters and not UTF-8 code units. - /// - /// For example, if a document vends separate keys for [`"\u{E9}"`]() ([`"é"`]()) and - /// [`"\u{65}\u{301}"`]() (also [`"é"`](), perhaps, because the document is - /// being used to bootstrap a unicode table), uniquing them by ``String`` - /// comparison would drop one of the values. - /// - /// To get a plain array of key-value pairs with no decoding interface, call the - /// document view’s ``BSON.Document/parse(_:)`` method instead. - /// - /// > Complexity: - /// O(*n*), where *n* is the number of fields in the source document. - /// - /// > Warning: - /// When you convert an object to a dictionary representation, you lose the ordering - /// information for the object items. Re-encoding it may produce a BSON - /// document that contains the same data, but does not compare equal. - @inlinable public - init(parsing bson:borrowing BSON.Document) throws - { - self.init() - try bson.parse - { - if case _? = self.index.updateValue($1, forKey: $0) - { - throw BSON.DocumentKeyError.duplicate($0) - } - } - } -} -extension BSON.DocumentDecoder:Sequence -{ - @inlinable public - func makeIterator() -> Iterator - { - .init(base: self.index.makeIterator()) - } -} -extension BSON.DocumentDecoder -{ - @inlinable public - func contains(_ key:CodingKey) -> Bool - { - self.index.keys.contains(key) - } - - @inlinable public consuming - func single() throws -> BSON.FieldDecoder - { - var single:BSON.FieldDecoder? = nil - for field:BSON.FieldDecoder in self - { - if case nil = single - { - single = field - } - else - { - throw BSON.SingleKeyError.multiple - } - } - guard let single - else - { - throw BSON.SingleKeyError.none - } - return single - } - - @inlinable public - subscript(key:CodingKey) -> BSON.OptionalDecoder - { - .init(key: key, value: self.index[key]) - } - @inlinable public - subscript(key:CodingKey) -> BSON.FieldDecoder? - { - self.index[key].map { .init(key: key, value: $0) } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.DocumentKeyError.swift b/Sources/BSONDecoding/Decoding/BSON.DocumentKeyError.swift deleted file mode 100644 index 8c230556..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.DocumentKeyError.swift +++ /dev/null @@ -1,40 +0,0 @@ -import TraceableErrors - -extension BSON -{ - /// A document had an invalid key scheme. - @frozen public - enum DocumentKeyError:Error where Key:Sendable - { - /// A document contained more than one field with the same key. - case duplicate(Key) - /// A document did not contain a field with the expected key. - case undefined(Key) - } -} -extension BSON.DocumentKeyError:Equatable where Key:Equatable -{ -} -extension BSON.DocumentKeyError:NamedError -{ - /// The name of the error. - /// - /// We customize this because otherwise the catcher of this error will mostly likely see - /// the coding key type name as `CodingKey`, and that wouldn’t be very helpful. - public - var name:String - { - "DocumentKeyError<\(String.init(reflecting: Key.self))>" - } - public - var message:String - { - switch self - { - case .duplicate(let key): - "duplicate key '\(key)'" - case .undefined(let key): - "undefined key '\(key)'" - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.List (ext).swift b/Sources/BSONDecoding/Decoding/BSON.List (ext).swift deleted file mode 100644 index 18503006..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.List (ext).swift +++ /dev/null @@ -1,23 +0,0 @@ -extension BSON.List:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast(with: \.list) - } -} -extension BSON.List -{ - /// Decorates the ``BSON.AnyValue``-yielding overload of this method with one that - /// enumerates the elements and yields them as fields. - @inlinable public - func parse(to decode:(_ field:BSON.FieldDecoder) throws -> ()) throws - { - var index:Int = 0 - try self.parse - { - try decode(.init(key: index, value: $0)) - index += 1 - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.ListDecoder.swift b/Sources/BSONDecoding/Decoding/BSON.ListDecoder.swift deleted file mode 100644 index 7a7b6bc1..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.ListDecoder.swift +++ /dev/null @@ -1,77 +0,0 @@ -extension BSON -{ - /// A thin wrapper around a native Swift array providing an efficient decoding - /// interface for a ``BSON/List``. - @frozen public - struct ListDecoder - { - public - var elements:[BSON.AnyValue] - - @inlinable public - init(_ elements:[BSON.AnyValue]) - { - self.elements = elements - } - } -} -extension BSON.ListDecoder:BSON.Decoder -{ - /// Attempts to unwrap and parse an array-decoder from the given variant. - /// - /// This method will only attempt to parse statically-typed BSON lists; it will not - /// inspect general documents to determine if they are valid lists. - /// - /// - Returns: - /// The payload of the variant, parsed to a list decoder, if it matches - /// ``AnyValue/list(_:) [case]`` and could be successfully parsed, nil otherwise. - /// - /// > Complexity: - // O(*n*), where *n* is the number of elements in the source list. - @inlinable public - init(parsing bson:borrowing BSON.AnyValue) throws - { - try self.init(parsing: try .init(bson: copy bson)) - } -} -extension BSON.ListDecoder -{ - /// Attempts to create a list decoder from the given list. - /// - /// To get a plain array with no decoding interface, call the list’s ``List/parse`` - /// method instead. Alternatively, you can use this function and access the - /// ``elements`` property afterwards. - /// - /// > Complexity: - // O(*n*), where *n* is the number of elements in the source list. - @inlinable public - init(parsing bson:borrowing BSON.List) throws - { - self.init(try bson.parse()) - } - - /// The shape of the list being decoded. - @inlinable public - var shape:BSON.Shape - { - .init(length: self.elements.count) - } -} -extension BSON.ListDecoder:RandomAccessCollection -{ - @inlinable public - var startIndex:Int - { - self.elements.startIndex - } - @inlinable public - var endIndex:Int - { - self.elements.endIndex - } - @inlinable public - subscript(index:Int) -> BSON.FieldDecoder - { - .init(key: index, value: self.elements[index]) - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.Shape.swift b/Sources/BSONDecoding/Decoding/BSON.Shape.swift deleted file mode 100644 index b570252e..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.Shape.swift +++ /dev/null @@ -1,63 +0,0 @@ -extension BSON -{ - /// An efficient interface for checking the shape of a decoded - /// list or binary array at run time. - @frozen public - struct Shape:Hashable, Sendable - { - public - let length:Int - - @inlinable public - init(length:Int) - { - self.length = length - } - } -} -extension BSON.Shape -{ - /// Throws an ``ShapeError`` if the relevant collection does not - /// contain the specified number of elements. - @inlinable public - func expect(length:Int) throws - { - guard self.length == length - else - { - throw BSON.ShapeError.init(invalid: self.length, expected: .length(length)) - } - } - /// Returns the quotient if the number of elements in the relevant collection is a multiple - /// of the specified stride, or throws a ``ShapeError`` otherwise. - /// If the stride is zero, this method also throws a ``ShapeError``, unless the length is - /// zero as well. - @inlinable public - func expect(multipleOf stride:Int) throws -> Int - { - if self.length == 0 - { - return 0 - } - - guard stride > 0, - case (let count, remainder: 0) = self.length.quotientAndRemainder(dividingBy: stride) - else - { - throw BSON.ShapeError.init(invalid: self.length, expected: .multiple(of: stride)) - } - - return count - } - /// Converts a boolean status code into a thrown ``ShapeError``. - /// To raise an error, return false from the closure. - @inlinable public - func expect(that predicate:(_ length:Int) throws -> Bool) throws - { - guard try predicate(self.length) - else - { - throw BSON.ShapeError.init(invalid: self.length) - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.ShapeError.Criteria.swift b/Sources/BSONDecoding/Decoding/BSON.ShapeError.Criteria.swift deleted file mode 100644 index 6b5ee567..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.ShapeError.Criteria.swift +++ /dev/null @@ -1,10 +0,0 @@ -extension BSON.ShapeError -{ - /// What shape you expected a list or binary array to have. - @frozen public - enum Criteria:Hashable, Sendable - { - case length(Int) - case multiple(of:Int) - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.ShapeError.swift b/Sources/BSONDecoding/Decoding/BSON.ShapeError.swift deleted file mode 100644 index 025c15fd..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.ShapeError.swift +++ /dev/null @@ -1,38 +0,0 @@ -extension BSON -{ - /// A list had an invalid number of elements or a binary array - /// had an invalid number of bytes. - @frozen public - struct ShapeError:Equatable, Error - { - public - let length:Int - public - let expected:Criteria? - - @inlinable public - init(invalid:Int, expected:Criteria? = nil) - { - self.length = invalid - self.expected = expected - } - } -} -extension BSON.ShapeError:CustomStringConvertible -{ - public - var description:String - { - switch self.expected - { - case nil: - "Invalid length (\(self.length))." - - case .length(let length)?: - "Invalid length (\(self.length)), expected \(length) elements." - - case .multiple(of: let stride)?: - "Invalid length (\(self.length)), expected multiple of \(stride)." - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.SingleKeyError.swift b/Sources/BSONDecoding/Decoding/BSON.SingleKeyError.swift deleted file mode 100644 index 454ac834..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.SingleKeyError.swift +++ /dev/null @@ -1,34 +0,0 @@ -import TraceableErrors - -extension BSON -{ - @frozen public - enum SingleKeyError:Equatable, Error - { - case none - case multiple - } -} -extension BSON.SingleKeyError:NamedError -{ - /// The name of the error. - /// - /// We customize this because otherwise the catcher of this error will mostly likely see - /// the coding key type name as `CodingKey`, and that wouldn’t be very helpful. - public - var name:String - { - "DocumentKeyError<\(String.init(reflecting: CodingKey.self))>" - } - public - var message:String - { - switch self - { - case .none: - "no keys in single-field document" - case .multiple: - "multiple keys in single-field document" - } - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.UTF8View (ext).swift b/Sources/BSONDecoding/Decoding/BSON.UTF8View (ext).swift deleted file mode 100644 index 39e162e8..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.UTF8View (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.UTF8View>:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast(with: \.utf8) - } -} diff --git a/Sources/BSONDecoding/Decoding/BSON.ValueError.swift b/Sources/BSONDecoding/Decoding/BSON.ValueError.swift deleted file mode 100644 index 075a9702..00000000 --- a/Sources/BSONDecoding/Decoding/BSON.ValueError.swift +++ /dev/null @@ -1,28 +0,0 @@ -extension BSON -{ - /// A decoder successfully to cast a variant to an expected value type, - /// but it was not a valid case of the expected destination type. - @frozen public - struct ValueError:Error where Value:Sendable - { - public - let value:Value - - @inlinable public - init(invalid value:Value) - { - self.value = value - } - } -} -extension BSON.ValueError:Equatable where Value:Equatable -{ -} -extension BSON.ValueError:CustomStringConvertible -{ - public - var description:String - { - "value '\(self.value)' does not encode a valid instance of type '\(Cases.self)'" - } -} diff --git a/Sources/BSONDecoding/Dictionary (ext).swift b/Sources/BSONDecoding/Dictionary (ext).swift deleted file mode 100644 index e01c793f..00000000 --- a/Sources/BSONDecoding/Dictionary (ext).swift +++ /dev/null @@ -1,25 +0,0 @@ -extension Dictionary:BSONDecodable where Key == BSON.Key, Value:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(bson: consume bson)) - } - /// Decodes an unordered dictionary from the given document. Dictionaries - /// are not ``BSONEncodable``, because round-tripping them loses the field - /// ordering information. - @inlinable public - init(bson:BSON.Document) throws - { - self.init() - try bson.parse - { - (field:BSON.FieldDecoder) in - - if case _? = self.updateValue(try field.decode(to: Value.self), forKey: field.key) - { - throw BSON.DocumentKeyError.duplicate(field.key.rawValue) - } - } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Decimal128 (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Decimal128 (ext).swift deleted file mode 100644 index 969fad72..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Decimal128 (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Decimal128:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Identifier (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Identifier (ext).swift deleted file mode 100644 index 1d9e9588..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Identifier (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Identifier:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Key (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Key (ext).swift deleted file mode 100644 index 2eaab296..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Key (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension BSON.Key:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Max (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Max (ext).swift deleted file mode 100644 index a1421d8b..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Max (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Max:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Min (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Min (ext).swift deleted file mode 100644 index 638f26b0..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Min (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Min:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Null (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Null (ext).swift deleted file mode 100644 index 88efcd80..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Null (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Null:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Regex (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Regex (ext).swift deleted file mode 100644 index 66b1dcef..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Regex (ext).swift +++ /dev/null @@ -1,13 +0,0 @@ -extension BSON.Regex:BSONDecodable -{ - /// Attempts to unwrap a ``BSON/Regex`` from the given variant. - /// The library always eagerly-parses regexes, so this initializer - /// does not perform any copying. - /// - /// > Complexity: O(1). - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/BSON.Timestamp (ext).swift b/Sources/BSONDecoding/Extensions/BSON.Timestamp (ext).swift deleted file mode 100644 index 7994036a..00000000 --- a/Sources/BSONDecoding/Extensions/BSON.Timestamp (ext).swift +++ /dev/null @@ -1,21 +0,0 @@ -extension BSON.Timestamp:BSONDecodable -{ - /// Attempts to cast a BSON variant backed by some storage type to a - /// MongoDB timestamp. The conversion is not a integer case, and will - /// succeed if and only if the variant has type ``BSON.AnyType/timestamp``. - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast - { - if case .timestamp(let value) = $0 - { - value - } - else - { - nil - } - } - } -} diff --git a/Sources/BSONDecoding/Extensions/Bool (ext).swift b/Sources/BSONDecoding/Extensions/Bool (ext).swift deleted file mode 100644 index 326bd329..00000000 --- a/Sources/BSONDecoding/Extensions/Bool (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension Bool:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Extensions/Character (ext).swift b/Sources/BSONDecoding/Extensions/Character (ext).swift deleted file mode 100644 index 0ca7f0cb..00000000 --- a/Sources/BSONDecoding/Extensions/Character (ext).swift +++ /dev/null @@ -1,24 +0,0 @@ -extension Character:BSONStringDecodable -{ - /// Witnesses `Character`’s ``BSONStringDecodable`` conformance, throwing - /// a ``BSON.ValueError`` instead of trapping on multi-character input. - /// - /// This is needed because its ``LosslessStringConvertible.init(_:)`` - /// witness traps on invalid input instead of returning nil, which causes - /// its default implementation (where `Self` is ``LosslessStringConvertible``) - /// to do the same. - @inlinable public - init(bson:BSON.UTF8View>) throws - { - let string:String = .init(bson: bson) - if string.startIndex < string.endIndex, - string.index(after: string.startIndex) == string.endIndex - { - self = string[string.startIndex] - } - else - { - throw BSON.ValueError.init(invalid: string) - } - } -} diff --git a/Sources/BSONDecoding/Extensions/Double (ext).swift b/Sources/BSONDecoding/Extensions/Double (ext).swift deleted file mode 100644 index d5dfb02c..00000000 --- a/Sources/BSONDecoding/Extensions/Double (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Double:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Float (ext).swift b/Sources/BSONDecoding/Extensions/Float (ext).swift deleted file mode 100644 index 44e1363c..00000000 --- a/Sources/BSONDecoding/Extensions/Float (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Float:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Float80 (ext).swift b/Sources/BSONDecoding/Extensions/Float80 (ext).swift deleted file mode 100644 index 7114baf9..00000000 --- a/Sources/BSONDecoding/Extensions/Float80 (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -#if arch(x86_64) -extension Float80:BSONDecodable -{ -} -#endif diff --git a/Sources/BSONDecoding/Extensions/Int (ext).swift b/Sources/BSONDecoding/Extensions/Int (ext).swift deleted file mode 100644 index 5aa540ab..00000000 --- a/Sources/BSONDecoding/Extensions/Int (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Int:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Int16 (ext).swift b/Sources/BSONDecoding/Extensions/Int16 (ext).swift deleted file mode 100644 index a82e07dc..00000000 --- a/Sources/BSONDecoding/Extensions/Int16 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Int16:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Int32 (ext).swift b/Sources/BSONDecoding/Extensions/Int32 (ext).swift deleted file mode 100644 index 6b9a09cd..00000000 --- a/Sources/BSONDecoding/Extensions/Int32 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Int32:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Int64 (ext).swift b/Sources/BSONDecoding/Extensions/Int64 (ext).swift deleted file mode 100644 index 87a058b4..00000000 --- a/Sources/BSONDecoding/Extensions/Int64 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Int64:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Int8 (ext).swift b/Sources/BSONDecoding/Extensions/Int8 (ext).swift deleted file mode 100644 index 46dda87e..00000000 --- a/Sources/BSONDecoding/Extensions/Int8 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Int8:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Milliseconds (ext).swift b/Sources/BSONDecoding/Extensions/Milliseconds (ext).swift deleted file mode 100644 index 4ebf142c..00000000 --- a/Sources/BSONDecoding/Extensions/Milliseconds (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Milliseconds:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Minutes (ext).swift b/Sources/BSONDecoding/Extensions/Minutes (ext).swift deleted file mode 100644 index b45a2c65..00000000 --- a/Sources/BSONDecoding/Extensions/Minutes (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Minutes:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Never (ext).swift b/Sources/BSONDecoding/Extensions/Never (ext).swift deleted file mode 100644 index 7b83d785..00000000 --- a/Sources/BSONDecoding/Extensions/Never (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension Never:BSONDecodable -{ - /// Always throws a ``BSON.TypecastError``. - @inlinable public - init(bson:BSON.AnyValue) throws - { - throw BSON.TypecastError.init(invalid: bson.type) - } -} diff --git a/Sources/BSONDecoding/Extensions/Seconds (ext).swift b/Sources/BSONDecoding/Extensions/Seconds (ext).swift deleted file mode 100644 index 03b90b25..00000000 --- a/Sources/BSONDecoding/Extensions/Seconds (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Seconds:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Set (ext).swift b/Sources/BSONDecoding/Extensions/Set (ext).swift deleted file mode 100644 index 23229a70..00000000 --- a/Sources/BSONDecoding/Extensions/Set (ext).swift +++ /dev/null @@ -1,17 +0,0 @@ -extension Set:BSONDecodable where Element:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(bson: consume bson)) - } - @inlinable public - init(bson:BSON.List) throws - { - self.init() - try bson.parse - { - self.update(with: try $0.decode(to: Element.self)) - } - } -} diff --git a/Sources/BSONDecoding/Extensions/String (ext).swift b/Sources/BSONDecoding/Extensions/String (ext).swift deleted file mode 100644 index 9a90d906..00000000 --- a/Sources/BSONDecoding/Extensions/String (ext).swift +++ /dev/null @@ -1,15 +0,0 @@ -extension String:BSONStringDecodable -{ - /// Copies and validates the backing storage of the given UTF-8 string to a native Swift - /// string, repairing invalid code units if needed. - /// - /// To convert a UTF-8 string backed by something that is not ``ArraySlice``, use - /// ``BSON.UTF8View.description`` instead. - /// - /// > Complexity: O(*n*), where *n* is the length of the string. - @inlinable public - init(bson:BSON.UTF8View>) - { - self.init(decoding: bson.bytes, as: Unicode.UTF8.self) - } -} diff --git a/Sources/BSONDecoding/Extensions/UInt (ext).swift b/Sources/BSONDecoding/Extensions/UInt (ext).swift deleted file mode 100644 index 395c22e3..00000000 --- a/Sources/BSONDecoding/Extensions/UInt (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension UInt:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/UInt16 (ext).swift b/Sources/BSONDecoding/Extensions/UInt16 (ext).swift deleted file mode 100644 index b2525e12..00000000 --- a/Sources/BSONDecoding/Extensions/UInt16 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension UInt16:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/UInt32 (ext).swift b/Sources/BSONDecoding/Extensions/UInt32 (ext).swift deleted file mode 100644 index 2213d189..00000000 --- a/Sources/BSONDecoding/Extensions/UInt32 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension UInt32:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/UInt64 (ext).swift b/Sources/BSONDecoding/Extensions/UInt64 (ext).swift deleted file mode 100644 index 1d4a4187..00000000 --- a/Sources/BSONDecoding/Extensions/UInt64 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension UInt64:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/UInt8 (ext).swift b/Sources/BSONDecoding/Extensions/UInt8 (ext).swift deleted file mode 100644 index cb98040e..00000000 --- a/Sources/BSONDecoding/Extensions/UInt8 (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension UInt8:BSONDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/Unicode.Scalar (ext).swift b/Sources/BSONDecoding/Extensions/Unicode.Scalar (ext).swift deleted file mode 100644 index ce651c92..00000000 --- a/Sources/BSONDecoding/Extensions/Unicode.Scalar (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -// note: the witness comes from `Unicode.Scalar`’s -// ``LosslessStringConvertible`` conformance. -extension Unicode.Scalar:BSONStringDecodable -{ -} diff --git a/Sources/BSONDecoding/Extensions/UnixMillisecond (ext).swift b/Sources/BSONDecoding/Extensions/UnixMillisecond (ext).swift deleted file mode 100644 index 7f5fe535..00000000 --- a/Sources/BSONDecoding/Extensions/UnixMillisecond (ext).swift +++ /dev/null @@ -1,10 +0,0 @@ -import UnixTime - -extension UnixMillisecond:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - self = try bson.cast { $0.as(Self.self) } - } -} diff --git a/Sources/BSONDecoding/Optional (ext).swift b/Sources/BSONDecoding/Optional (ext).swift deleted file mode 100644 index bd7ddb3a..00000000 --- a/Sources/BSONDecoding/Optional (ext).swift +++ /dev/null @@ -1,15 +0,0 @@ -extension Optional:BSONDecodable where Wrapped:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - if case .null = bson - { - self = .none - } - else - { - self = .some(try .init(bson: bson)) - } - } -} diff --git a/Sources/BSONDecoding/README.md b/Sources/BSONDecoding/README.md deleted file mode 100644 index cd4aae9f..00000000 --- a/Sources/BSONDecoding/README.md +++ /dev/null @@ -1 +0,0 @@ -# ``/BSONDecoding`` diff --git a/Sources/BSONDecoding/exports.swift b/Sources/BSONDecoding/exports.swift deleted file mode 100644 index 39f8f8b5..00000000 --- a/Sources/BSONDecoding/exports.swift +++ /dev/null @@ -1 +0,0 @@ -@_exported import enum BSONABI.BSON diff --git a/Sources/BSONDecodingTests/DecodeBinary.swift b/Sources/BSONDecodingTests/DecodeBinary.swift deleted file mode 100644 index 1b279850..00000000 --- a/Sources/BSONDecodingTests/DecodeBinary.swift +++ /dev/null @@ -1,19 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -enum DecodeBinary -{ - @Test - static func MD5() throws - { - let md5:BSON.BinaryView> = .init(subtype: .md5, - bytes: [0xff, 0xfe, 0xfd]) - let document:BSON.Document = ["md5": .binary(md5)] - - let decoder:BSON.DocumentDecoder = try .init(parsing: document) - let decoded:BSON.BinaryView> = try decoder["md5"].decode() - - #expect(md5 == decoded) - } -} diff --git a/Sources/BSONDecodingTests/DecodeDocument.swift b/Sources/BSONDecodingTests/DecodeDocument.swift deleted file mode 100644 index d6f04fb4..00000000 --- a/Sources/BSONDecodingTests/DecodeDocument.swift +++ /dev/null @@ -1,111 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -struct DecodeDocument -{ - private - let bson:BSON.DocumentDecoder - - init() throws - { - let bson:BSON.Document = ["present": .null, "inhabited": true] - self.bson = try .init(parsing: bson) - } -} -extension DecodeDocument -{ - @Test - static func KeyNotUnique() throws - { - #expect(throws: BSON.DocumentKeyError.duplicate("present")) - { - let degenerate:BSON.Document = [ - "present": .null, - "present": true, - ] - let decoder:BSON.DocumentDecoder = try .init(parsing: degenerate) - _ = try decoder["not-present"].decode(to: Bool.self) - } - } -} -extension DecodeDocument -{ - @Test - func KeyNotPresent() throws - { - #expect(throws: BSON.DocumentKeyError.undefined("not-present")) - { - try self.bson["not-present"].decode(to: Bool.self) - } - } - - @Test - func KeyNotMatching() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.TypecastError>>.init(invalid: .bool), - in: "inhabited")) - { - try self.bson["inhabited"].decode(to: String.self) - } - } - - @Test - func KeyNotMatchingInhabited() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.TypecastError.init(invalid: .null), - in: "present")) - { - try self.bson["present"].decode(to: Bool.self) - } - } - - @Test - func KeyInhabited() throws - { - #expect(try true == self.bson["inhabited"].decode(to: Bool?.self)) - } - - @Test - func KeyMatching() throws - { - #expect(try true == self.bson["inhabited"].decode()) - } - - @Test - func KeyNull() throws - { - #expect(try nil == self.bson["present"].decode(to: Bool?.self)) - } - - @Test - func KeyOptional() throws - { - #expect(try nil == self.bson["not-present"]?.decode(to: Bool.self)) - } - - @Test - func KeyOptionalNull() throws - { - #expect(try .some(nil) == self.bson["present"]?.decode(to: Bool?.self)) - } - - @Test - func KeyOptionalInhabited() throws - { - #expect(try true == self.bson["inhabited"]?.decode(to: Bool?.self)) - } - - @Test - func KeyOptionalNotInhabited() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.TypecastError.init(invalid: .null), - in: "present")) - { - try self.bson["present"]?.decode(to: Bool.self) - } - } -} diff --git a/Sources/BSONDecodingTests/DecodeList.swift b/Sources/BSONDecodingTests/DecodeList.swift deleted file mode 100644 index 08790756..00000000 --- a/Sources/BSONDecodingTests/DecodeList.swift +++ /dev/null @@ -1,126 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -struct DecodeList -{ - private - let bson:BSON.DocumentDecoder - - init() throws - { - let bson:BSON.Document = [ - "none": [], - "two": ["a", "b"], - "three": ["a", "b", "c"], - "four": ["a", "b", "c", "d"], - - "heterogenous": ["a", "b", 0, "d"], - ] - - self.bson = try .init(parsing: bson) - } -} -extension DecodeList -{ - @Test - func NoneToTwo() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ShapeError.init(invalid: 0, expected: .length(2)), - in: "none")) - { - try self.bson["none"].decode { try $0.shape.expect(length: 2) } - } - } - - @Test - func TwoToTwo() throws - { - #expect(try ["a", "b"] == self.bson["two"].decode - { - try $0.shape.expect(length: 2) - return try $0.map { try $0.decode(to: String.self) } - }) - } - - @Test - func ThreeToTwo() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ShapeError.init(invalid: 3, expected: .length(2)), - in: "three")) - { - try self.bson["three"].decode { try $0.shape.expect(length: 2) } - } - } - - @Test - func ThreeByTwo() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ShapeError.init(invalid: 3, expected: .multiple(of: 2)), - in: "three")) - { - try self.bson["three"].decode { try $0.shape.expect(multipleOf: 2) } - } - } - - @Test - func FourByTwo() throws - { - #expect(try ["a", "b", "c", "d"] == self.bson["four"].decode - { - _ = try $0.shape.expect(multipleOf: 2) - return try $0.map { try $0.decode(to: String.self) } - }) - } - - @Test - func Map() throws - { - #expect(try ["a", "b", "c", "d"] == self.bson["four"].decode()) - } - - @Test - func MapInvalid() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.DecodingError.init( - BSON.TypecastError>>.init( - invalid: .int32), - in: 2), - in: "heterogenous")) - { - try self.bson["heterogenous"].decode(to: [String].self) - } - } - - @Test - func Element() throws - { - #expect(try "c" == self.bson["four"].decode - { - try $0.shape.expect { 2 < $0 } - return try $0[2].decode(to: String.self) - }) - } - - @Test - func ElementInvalid() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.DecodingError.init( - BSON.TypecastError>>.init( - invalid: .int32), - in: 2), - in: "heterogenous")) - { - try self.bson["heterogenous"].decode - { - try $0.shape.expect { 2 < $0 } - return try $0[2].decode(to: String.self) - } - } - } -} diff --git a/Sources/BSONDecodingTests/DecodeNumeric.swift b/Sources/BSONDecodingTests/DecodeNumeric.swift deleted file mode 100644 index 7f2529dd..00000000 --- a/Sources/BSONDecodingTests/DecodeNumeric.swift +++ /dev/null @@ -1,57 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -struct DecodeNumeric -{ - private - let bson:BSON.DocumentDecoder - - init() throws - { - let bson:BSON.Document = - [ - "int32": .int32(0x7fff_ffff), - "int64": .int64(0x7fff_ffff_ffff_ffff), - "uint64": .timestamp(0x7fff_ffff_ffff_ffff), - ] - - self.bson = try .init(parsing: bson) - } -} -extension DecodeNumeric -{ - @Test - func Int32ToUInt8() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.IntegerOverflowError.int32(0x7fff_ffff), - in: "int32")) - { - try self.bson["int32"].decode(to: UInt8.self) - } - } - - @Test - func Int32ToInt32() throws - { - #expect(try 0x7fff_ffff == self.bson["int32"].decode(to: Int32.self)) - } - - @Test - func Int32ToInt() throws - { - #expect(try 0x7fff_ffff == self.bson["int32"].decode(to: Int.self)) - } - - @Test - func Int64ToInt() throws - { - #expect(try 0x7fff_ffff_ffff_ffff == self.bson["int64"].decode(to: Int.self)) - } - @Test - func UInt64ToInt() throws - { - #expect(try 0x7fff_ffff_ffff_ffff == self.bson["uint64"].decode(to: Int.self)) - } -} diff --git a/Sources/BSONDecodingTests/DecodeString.swift b/Sources/BSONDecodingTests/DecodeString.swift deleted file mode 100644 index 52a7d5cc..00000000 --- a/Sources/BSONDecodingTests/DecodeString.swift +++ /dev/null @@ -1,74 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -struct DecodeString -{ - private - let bson:BSON.DocumentDecoder - - init() throws - { - let bson:BSON.Document = - [ - "string": "e\u{0301}e\u{0301}", - "character": "e\u{0301}", - "unicode-scalar": "e", - ] - - self.bson = try .init(parsing: bson) - } -} -extension DecodeString -{ - @Test - func UnicodeScalarFromString() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ValueError.init(invalid: "e\u{0301}e\u{0301}"), - in: "string")) - { - try self.bson["string"].decode(to: Unicode.Scalar.self) - } - } - - @Test - func UnicodeScalarFromCharacter() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ValueError.init(invalid: "e\u{0301}"), - in: "character")) - { - try self.bson["character"].decode(to: Unicode.Scalar.self) - } - } - - @Test - func UnicodeScalarFromUnicodeScalar() throws - { - #expect(try "e" == self.bson["unicode-scalar"].decode(to: Unicode.Scalar.self)) - } - - @Test - func CharacterFromString() throws - { - #expect(throws: BSON.DecodingError.init( - BSON.ValueError.init(invalid: "e\u{0301}e\u{0301}"), - in: "string")) - { - try self.bson["string"].decode(to: Character.self) - } - } - - @Test - func CharacterFromCharacter() throws - { - #expect(try "e\u{0301}" == self.bson["character"].decode(to: Character.self)) - } - - @Test - func StringFromString() throws - { - #expect(try "e\u{0301}e\u{0301}" == self.bson["string"].decode(to: String.self)) - } -} diff --git a/Sources/BSONDecodingTests/DecodeVoid.swift b/Sources/BSONDecodingTests/DecodeVoid.swift deleted file mode 100644 index 0f34abcf..00000000 --- a/Sources/BSONDecodingTests/DecodeVoid.swift +++ /dev/null @@ -1,42 +0,0 @@ -import BSONDecoding -import Testing - -@Suite -struct DecodeVoid -{ - private - let bson:BSON.DocumentDecoder - - init() throws - { - let bson:BSON.Document = - [ - "null": .null, - "max": .max, - "min": .min, - ] - - self.bson = try .init(parsing: bson) - } -} -extension DecodeVoid -{ - @Test - func Null() throws - { - #expect(try BSON.Null.init() == self.bson["null"].decode()) - } - - @Test - func Max() throws - { - #expect(try BSON.Max.init() == self.bson["max"].decode()) - } - - @Test - func Min() throws - { - #expect(try BSON.Min.init() == self.bson["min"].decode()) - } -} - diff --git a/Sources/BSONEncoding/Array (ext).swift b/Sources/BSONEncoding/Array (ext).swift deleted file mode 100644 index 6d8ddd6f..00000000 --- a/Sources/BSONEncoding/Array (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension Array:BSONListEncodable, BSONEncodable where Element:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Dictionary (ext).swift b/Sources/BSONEncoding/Dictionary (ext).swift deleted file mode 100644 index 4dd09004..00000000 --- a/Sources/BSONEncoding/Dictionary (ext).swift +++ /dev/null @@ -1,11 +0,0 @@ -/// We generally do *not* want dictionaries to be ``BSONEncodable``, -/// and dictionary literals generate dictionaries by default. -extension [String: Never]:BSONEncodable -{ - /// Encodes this dictionary as an empty document. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(document: [:]) - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONArrayEncodable.swift b/Sources/BSONEncoding/Encodability/BSONArrayEncodable.swift deleted file mode 100644 index ea40c1dd..00000000 --- a/Sources/BSONEncoding/Encodability/BSONArrayEncodable.swift +++ /dev/null @@ -1,22 +0,0 @@ -/// A type that can be encoded to a BSON binary array. Not to be confused with -/// ``BSONListEncodable``. -public -protocol BSONArrayEncodable:BSONBinaryEncodable -{ - associatedtype CodingElement //:_Trivial -} -extension BSONArrayEncodable where Self:RandomAccessCollection -{ - /// Encodes the elements of this collection to the binary encoder by densely copying each - /// element’s raw memory representation, without any padding. - @inlinable public - func encode(to bson:inout BSON.BinaryEncoder) - { - bson.reserve(another: count * MemoryLayout.size) - - for trivial:CodingElement in self - { - withUnsafeBytes(of: trivial) { bson += $0 } - } - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONBinaryEncodable.swift b/Sources/BSONEncoding/Encodability/BSONBinaryEncodable.swift deleted file mode 100644 index cfea1ed8..00000000 --- a/Sources/BSONEncoding/Encodability/BSONBinaryEncodable.swift +++ /dev/null @@ -1,18 +0,0 @@ -public -protocol BSONBinaryEncodable:BSONEncodable -{ - /// Populates a binary array from this instance by encoding to the parameter, possibly - /// updating the array’s binary ``BSON.BinaryEncoder/subtype`` as well. - /// - /// The implementation must not assume the encoding container is initially empty, because it - /// may be the owner of the final output buffer. - func encode(to bson:inout BSON.BinaryEncoder) -} -extension BSONBinaryEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.encode(to: &field[as: BSON.BinaryEncoder.self]) - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONDocumentEncodable.swift b/Sources/BSONEncoding/Encodability/BSONDocumentEncodable.swift deleted file mode 100644 index c4375b0b..00000000 --- a/Sources/BSONEncoding/Encodability/BSONDocumentEncodable.swift +++ /dev/null @@ -1,28 +0,0 @@ -/// A type that can be encoded to a BSON document. This protocol exists to -/// allow types that define ``CodingKey`` to encode themselves using a -/// ``BSON.DocumentEncoder``. -/// -/// In general, you should *not* require this protocol if the intention is -/// simply to constrain a type parameter to a type that can only encode a -/// BSON document. -public -protocol BSONDocumentEncodable:BSONEncodable -{ - associatedtype CodingKey:RawRepresentable = BSON.Key - - /// Creates a document from this instance by encoding to - /// the parameter. - /// - /// The implementation must not assume the encoding container - /// is initially empty, because it may be the owner of the - /// final output buffer. - func encode(to bson:inout BSON.DocumentEncoder) -} -extension BSONDocumentEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.encode(to: &field[as: BSON.DocumentEncoder.self]) - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONEncodable.swift b/Sources/BSONEncoding/Encodability/BSONEncodable.swift deleted file mode 100644 index 20915086..00000000 --- a/Sources/BSONEncoding/Encodability/BSONEncodable.swift +++ /dev/null @@ -1,72 +0,0 @@ -import BSONABI - -/// A type that can be encoded to a BSON variant value. -public -protocol BSONEncodable -{ - func encode(to field:inout BSON.FieldEncoder) -} -extension BSONEncodable where Self:BSONRepresentable, BSONRepresentation:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.bson.encode(to: &field) - } -} -extension BSONEncodable where Self:RawRepresentable, RawValue:BSONEncodable -{ - /// Returns the ``encode(to:) [7NT06]`` witness of this type’s - /// ``RawRepresentable/rawValue``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.rawValue.encode(to: &field) - } -} - -@available(*, unavailable, message: "Currently useless due to a compiler bug!") -extension BSONEncodable where Self == BSON.Min -{ - /// A shorthand for encoding a ``BSON.Min`` value. - @inlinable public static - var min:Self { .init() } -} -@available(*, unavailable, message: "Currently useless due to a compiler bug!") -extension BSONEncodable where Self == BSON.Max -{ - /// A shorthand for encoding a ``BSON.Max`` value. - @inlinable public static - var max:Self { .init() } -} -@available(*, unavailable, message: "Currently useless due to a compiler bug!") -extension BSONEncodable where Self == BSON.Null -{ - /// A shorthand for encoding an explicit ``BSON.Null`` value. - @inlinable public static - var null:Self { .init() } -} - - -@available(*, deprecated, - message: "UInt64 is not recommended for BSON that will be handled by MongoDB.") -extension UInt64:BSONEncodable -{ - /// Encodes this integer as a value of type ``BSON.AnyType/timestamp``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(timestamp: .init(self)) - } -} -@available(*, deprecated, - message: "UInt is not recommended for BSON that will be handled by MongoDB.") -extension UInt:BSONEncodable -{ - /// Encodes this integer as a value of type ``BSON.AnyType/timestamp``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(timestamp: .init(UInt64.init(self))) - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONListEncodable.swift b/Sources/BSONEncoding/Encodability/BSONListEncodable.swift deleted file mode 100644 index b344b151..00000000 --- a/Sources/BSONEncoding/Encodability/BSONListEncodable.swift +++ /dev/null @@ -1,43 +0,0 @@ -/// A type that can be encoded to a BSON list. This protocol exists to -/// allow types that also conform to ``Sequence`` to opt-in to automatic -/// ``BSONEncodable`` conformance as well. -/// -/// In general, you should *not* require this protocol if the intention is -/// simply to constrain a type parameter to a type that can only encode a -/// BSON list. For example, ``Array`` always encodes itself as a list, but -/// it does not conform to this protocol. -/// -/// > Tip: -/// Not every type that *can* be ``BSONListEncodable`` *should* be -/// ``BSONListEncodable``. For example, ``Set`` is a ``Sequence``, but -/// it does not encode itself deterministically. So encoding instances -/// of ``Set`` directly is usually not what you want. -public -protocol BSONListEncodable:BSONEncodable -{ - /// Populates a list from this instance by encoding to the parameter. - /// - /// The implementation must not assume the encoding container is initially empty, because it - /// may be the owner of the final output buffer. - func encode(to bson:inout BSON.ListEncoder) -} -extension BSONListEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.encode(to: &field[as: BSON.ListEncoder.self]) - } -} -extension BSONListEncodable where Self:Sequence, Element:BSONEncodable -{ - /// Encodes this sequence as a value of type ``BSON.AnyType/list``. - @inlinable public - func encode(to bson:inout BSON.ListEncoder) - { - for element:Element in self - { - bson.append(element) - } - } -} diff --git a/Sources/BSONEncoding/Encodability/BSONStringEncodable.swift b/Sources/BSONEncoding/Encodability/BSONStringEncodable.swift deleted file mode 100644 index 60a060ea..00000000 --- a/Sources/BSONEncoding/Encodability/BSONStringEncodable.swift +++ /dev/null @@ -1,36 +0,0 @@ -/// A type that can be encoded to a BSON UTF-8 string. This protocol -/// exists to allow types that also conform to ``LosslessStringConvertible`` -/// to opt-in to automatic ``BSONEncodable`` conformance as well. -/// -/// In general, you should *not* require this protocol if the intention is -/// simply to constrain a type parameter to a type that can only encode a -/// BSON string. -/// -/// > Tip: -/// Not every type that *can* be ``BSONStringEncodable`` *should* be -/// ``BSONStringEncodable``. For example, ``Int`` is -/// ``CustomStringConvertible``, but it should encode itself as an -/// integer, not a string. -public -protocol BSONStringEncodable:BSONEncodable -{ - /// Converts an instance of this type to a string. This requirement - /// restates its counterpart in ``LosslessStringConvertible`` if - /// `Self` also conforms to it. - var description:String { get } -} -extension BSONStringEncodable -{ - /// Encodes the ``description`` of this instance as a BSON UTF-8 string. - /// - /// This default implementation is provided on an extension on a - /// dedicated protocol rather than an extension on ``BSONEncodable`` - /// itself to prevent unexpected behavior for types (such as ``Double``) - /// who implement ``LosslessStringConvertible``, but expect to be - /// encoded as something besides a UTF-8 string. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.description.encode(to: &field) - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.BinaryEncoder.swift b/Sources/BSONEncoding/Encoding/BSON.BinaryEncoder.swift deleted file mode 100644 index e233b036..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.BinaryEncoder.swift +++ /dev/null @@ -1,79 +0,0 @@ -extension BSON -{ - @frozen public - struct BinaryEncoder - { - @usableFromInline - var output:BSON.Output - @usableFromInline - var first:Int - - @inlinable - init(_ output:BSON.Output, first:Int) - { - self.output = output - self.first = first - } - } -} -extension BSON.BinaryEncoder -{ - @inlinable public - var subtype:BSON.BinarySubtype - { - get - { - .init(unchecked: self.output.destination[self.first]) - } - set(value) - { - self.output.destination[self.first] = value.rawValue - } - } - - @inlinable - var bytes:ArraySlice - { - self.output.destination[self.output.destination.index(after: self.first)...] - } -} -extension BSON.BinaryEncoder:BSON.Encoder -{ - /// Creates a binary encoder by taking ownership the given output buffer, initializing the - /// binary subtype to ``BSON.BinarySubtype/generic``. - @inlinable public - init(_ output:consuming BSON.Output) - { - let subtype:BSON.BinarySubtype = .generic - let index:Int = output.destination.endIndex - output.append(subtype.rawValue) - - self.init(output, first: index) - } - - @inlinable public consuming - func move() -> BSON.Output { self.output } - - @inlinable public static - var frame:BSON.BinaryFrame { .binary } -} -extension BSON.BinaryEncoder -{ - @inlinable public static - func += (self:inout Self, bytes:some Sequence) - { - self.output.append(bytes) - } - - @inlinable public mutating - func append(_ byte:UInt8) - { - self.output.append(byte) - } - - @inlinable public mutating - func reserve(another bytes:Int) - { - self.output.reserve(another: bytes) - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.Document (ext).swift b/Sources/BSONEncoding/Encoding/BSON.Document (ext).swift deleted file mode 100644 index 12a23963..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.Document (ext).swift +++ /dev/null @@ -1,86 +0,0 @@ -extension BSON.Document:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(document: self) - } -} -extension BSON.Document -{ - @inlinable public - subscript(_:CodingKey.Type) -> BSON.DocumentEncoder - { - mutating - _read { yield self.output[as: BSON.DocumentEncoder.self] } - _modify { yield &self.output[as: BSON.DocumentEncoder.self] } - } -} -extension BSON.Document -{ - @inlinable public - subscript(with key:some RawRepresentable) -> BSON.FieldEncoder - { - _read { yield self.output[with: .init(key)] } - _modify { yield &self.output[with: .init(key)] } - } -} - -extension BSON.Document -{ - @inlinable public - init(encoding fields:__shared some Sequence<(key:BSON.Key, value:Encodable)>) - where Encodable:BSONEncodable - { - self.init - { - for (key, value):(BSON.Key, Encodable) in fields - { - $0[key] = value - } - } - } - @inlinable public - init(encoding encodable:__shared some BSONDocumentEncodable) - { - self.init(with: encodable.encode(to:)) - } - - @inlinable public - init(_:CodingKey.Type = CodingKey.self, - with encode:(inout BSON.DocumentEncoder) throws -> ()) rethrows - { - self.init() - try encode(&self.output[as: BSON.DocumentEncoder.self]) - } -} - -@available(*, unavailable, message: "These APIs have moved to BSON.Document") -extension BSONEncodable where Self == BSON.Document -{ - @inlinable public - init(encoding fields:__shared some Sequence<(key:BSON.Key, value:Encodable)>) - where Encodable:BSONEncodable - { - self.init - { - for (key, value):(BSON.Key, Encodable) in fields - { - $0[key] = value - } - } - } - @inlinable public - init(encoding encodable:__shared some BSONDocumentEncodable) - { - self.init(with: encodable.encode(to:)) - } - - @inlinable public - init(_:CodingKey.Type = CodingKey.self, - with populate:(inout BSON.DocumentEncoder) throws -> ()) rethrows - { - self.init() - try populate(&self.output[as: BSON.DocumentEncoder.self]) - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.DocumentEncoder.swift b/Sources/BSONEncoding/Encoding/BSON.DocumentEncoder.swift deleted file mode 100644 index c7a0853e..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.DocumentEncoder.swift +++ /dev/null @@ -1,58 +0,0 @@ -extension BSON -{ - @frozen public - struct DocumentEncoder where CodingKey:RawRepresentable - { - @usableFromInline internal - var output:BSON.Output - - @inlinable public - init(_ output:BSON.Output) - { - self.output = output - } - } -} -extension BSON.DocumentEncoder:BSON.Encoder -{ - @inlinable public consuming - func move() -> BSON.Output { self.output } - - @inlinable public static - var frame:BSON.DocumentFrame { .document } -} -extension BSON.DocumentEncoder -{ - @inlinable public - subscript(key:CodingKey) -> BSON.FieldEncoder - { - _read { yield self.output[with: .init(key)] } - _modify { yield &self.output[with: .init(key)] } - } - @inlinable public - subscript(with key:some RawRepresentable) -> BSON.FieldEncoder - { - _read { yield self.output[with: .init(key)] } - _modify { yield &self.output[with: .init(key)] } - } -} -extension BSON.DocumentEncoder -{ - /// Appends the given key-value pair to this document builder, encoding the - /// value as the field value using its ``BSONEncodable`` implementation. - /// - /// Type inference will always prefer one of the concretely-typed subscript - /// overloads over this one. - /// - /// The getter always returns nil. - /// - /// Every non-nil assignment to this subscript (including mutations - /// that leave the value in a non-nil state after returning) will add - /// a new field to the document, even if the key is the same. - @inlinable public - subscript(key:CodingKey) -> Value? where Value:BSONEncodable - { - get { nil } - set (value) { value?.encode(to: &self[with: key]) } - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.FieldEncoder (ext).swift b/Sources/BSONEncoding/Encoding/BSON.FieldEncoder (ext).swift deleted file mode 100644 index 2f13cd65..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.FieldEncoder (ext).swift +++ /dev/null @@ -1,17 +0,0 @@ -extension BSON.FieldEncoder -{ - /// A shorthand for binding this field encoder to a ``DocumentEncoder``. - @inlinable public mutating - func callAsFunction(_:CodingKey.Type, - yield:(inout BSON.DocumentEncoder) -> ()) -> Void - { - yield(&self[as: BSON.DocumentEncoder.self]) - } - /// A shorthand for binding this field encoder to a ``ListEncoder``. - @inlinable public mutating - func callAsFunction(_:Int.Type, - yield:(inout BSON.ListEncoder) -> ()) -> Void - { - yield(&self[as: BSON.ListEncoder.self]) - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.List (ext).swift b/Sources/BSONEncoding/Encoding/BSON.List (ext).swift deleted file mode 100644 index 058991bf..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.List (ext).swift +++ /dev/null @@ -1,30 +0,0 @@ -extension BSON.List:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(list: self) - } -} -extension BSON.List -{ - /// Creates an empty list, and initializes it with the given closure. - @inlinable public - init(with encode:(inout BSON.ListEncoder) throws -> ()) rethrows - { - self.init() - try encode(&self.output[as: BSON.ListEncoder.self]) - } - - @inlinable public - init(elements:some Sequence) where Encodable:BSONEncodable - { - self.init - { - for element:Encodable in elements - { - $0.append(element) - } - } - } -} diff --git a/Sources/BSONEncoding/Encoding/BSON.ListEncoder.Index.swift b/Sources/BSONEncoding/Encoding/BSON.ListEncoder.Index.swift deleted file mode 100644 index 4e66c798..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.ListEncoder.Index.swift +++ /dev/null @@ -1,13 +0,0 @@ -extension BSON.ListEncoder -{ - /// A syntactical abstraction used to express the “end index” of a list. This type has no - /// inhabitants. - @frozen public - enum Index {} -} -extension BSON.ListEncoder.Index -{ - /// A syntactical symbol used to express the “end index” of an list. - @inlinable public - static prefix func + (_:Self) {} -} diff --git a/Sources/BSONEncoding/Encoding/BSON.ListEncoder.swift b/Sources/BSONEncoding/Encoding/BSON.ListEncoder.swift deleted file mode 100644 index afcfaaac..00000000 --- a/Sources/BSONEncoding/Encoding/BSON.ListEncoder.swift +++ /dev/null @@ -1,79 +0,0 @@ -extension BSON -{ - /// A type that can encode BSON list elements directly to an output buffer. - /// - /// Like ``DocumentEncoder``, which works with ``BSONDocumentEncodable``, - /// this type has its own companion protocol ``BSONListEncodable``, which is used to - /// bootstrap faster ``BSONEncodable`` conformances for ``Sequence``s. - @frozen public - struct ListEncoder - { - @usableFromInline - var output:BSON.Output - @usableFromInline - var count:Int - - @inlinable public - init(_ output:BSON.Output) - { - self.output = output - self.count = 0 - } - } -} -extension BSON.ListEncoder:BSON.Encoder -{ - @inlinable public consuming - func move() -> BSON.Output { self.output } - - @inlinable public static - var frame:BSON.DocumentFrame { .list } -} -extension BSON.ListEncoder -{ - @inlinable public mutating - func append(with encode:(inout BSON.FieldEncoder) -> ()) - { - encode(&self.output[with: .init(index: self.count)]) - self.count += 1 - } -} -extension BSON.ListEncoder -{ - @inlinable mutating - func append(_ value:some BSONEncodable) - { - self.append(with: value.encode(to:)) - } -} -extension BSON.ListEncoder -{ - /// Appends a value to the list if non-nil, does nothing otherwise. - /// - /// Why a subscript and not an `append` method? Because we often want to optionally append a - /// value while building a list, and the subscript syntax is more convenient for that. - @inlinable public - subscript(_:(Index) -> Void) -> Encodable? where Encodable:BSONEncodable - { - get { nil } - set (value) - { - if let value:Encodable - { - self.append(value) - } - } - } - - @inlinable public mutating - func callAsFunction(_ yield:(inout BSON.ListEncoder) -> ()) - { - self.append { yield(&$0[as: BSON.ListEncoder.self]) } - } - @inlinable public mutating - func callAsFunction(_:CodingKey.Type = CodingKey.self, - _ yield:(inout BSON.DocumentEncoder) -> ()) - { - self.append { yield(&$0[as: BSON.DocumentEncoder.self]) } - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.AnyType (ext).swift b/Sources/BSONEncoding/Extensions/BSON.AnyType (ext).swift deleted file mode 100644 index 4749912b..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.AnyType (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension BSON.AnyType:BSONEncodable -{ - /// Encodes this metatype as a value of type ``BSON.AnyType/int32``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(int32: .init(self.rawValue)) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.BinaryView (ext).swift b/Sources/BSONEncoding/Extensions/BSON.BinaryView (ext).swift deleted file mode 100644 index 479cff7d..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.BinaryView (ext).swift +++ /dev/null @@ -1,28 +0,0 @@ -extension BSON.BinaryView:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(binary: self) - } -} - -extension BSON.BinaryView> -{ - @inlinable public - init(with encode:(inout BSON.BinaryEncoder) throws -> ()) rethrows - { - /// The ``BinaryEncoder`` will always write a superfluous subtype byte, so we might as - /// well preallocate the capacity for it. - var output:BSON.Output = .init(capacity: 1) - - /// This shouldn’t copy, as ``BinaryEncoder.move`` does not write to the buffer. - let (subtype, bytes):(BSON.BinarySubtype, ArraySlice) = try - { - try encode(&$0) - return ($0.subtype, $0.bytes) - } (&output[as: BSON.BinaryEncoder.self]) - - self.init(subtype: subtype, bytes: bytes) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Decimal128 (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Decimal128 (ext).swift deleted file mode 100644 index 10ba97a9..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Decimal128 (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Decimal128:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(decimal128: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Identifier (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Identifier (ext).swift deleted file mode 100644 index 97bc6ad6..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Identifier (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Identifier:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(id: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Key (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Key (ext).swift deleted file mode 100644 index 7ba33390..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Key (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension BSON.Key:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Max (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Max (ext).swift deleted file mode 100644 index a62c4195..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Max (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Max:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(max: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Min (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Min (ext).swift deleted file mode 100644 index e851cff6..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Min (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Min:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(min: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Null (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Null (ext).swift deleted file mode 100644 index de7030b3..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Null (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension BSON.Null:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(null: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Regex (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Regex (ext).swift deleted file mode 100644 index e7ee82e5..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Regex (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension BSON.Regex:BSONEncodable -{ - /// Encodes this regex as a value of type ``BSON.AnyType/regex``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(regex: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.Timestamp (ext).swift b/Sources/BSONEncoding/Extensions/BSON.Timestamp (ext).swift deleted file mode 100644 index e2291d5e..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.Timestamp (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension BSON.Timestamp:BSONEncodable -{ - /// Encodes this timestamp as a ``BSON.AnyValue/timestamp(_:) [case]``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(timestamp: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/BSON.UTF8View (ext).swift b/Sources/BSONEncoding/Extensions/BSON.UTF8View (ext).swift deleted file mode 100644 index 704a0ca1..00000000 --- a/Sources/BSONEncoding/Extensions/BSON.UTF8View (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension BSON.UTF8View:BSONEncodable -{ - /// Encodes this UTF-8 string as a ``BSON.AnyType/string``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(string: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/Bool (ext).swift b/Sources/BSONEncoding/Extensions/Bool (ext).swift deleted file mode 100644 index 84eb07a6..00000000 --- a/Sources/BSONEncoding/Extensions/Bool (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension Bool:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(bool: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/Character (ext).swift b/Sources/BSONEncoding/Extensions/Character (ext).swift deleted file mode 100644 index 8c9d358a..00000000 --- a/Sources/BSONEncoding/Extensions/Character (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension Character:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.description.encode(to: &field) - } -} diff --git a/Sources/BSONEncoding/Extensions/Double (ext).swift b/Sources/BSONEncoding/Extensions/Double (ext).swift deleted file mode 100644 index 6ee73af8..00000000 --- a/Sources/BSONEncoding/Extensions/Double (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension Double:BSONEncodable -{ - /// Encodes this metatype as a value of type ``BSON.AnyType/double``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(double: .init(self)) - } -} diff --git a/Sources/BSONEncoding/Extensions/Int (ext).swift b/Sources/BSONEncoding/Extensions/Int (ext).swift deleted file mode 100644 index 8c4b2f2b..00000000 --- a/Sources/BSONEncoding/Extensions/Int (ext).swift +++ /dev/null @@ -1,17 +0,0 @@ -extension Int:BSONEncodable -{ - /// Encodes this integer as a value of type ``BSON.AnyType/int32`` if it can be represented - /// exactly, or ``BSON.AnyType/int64`` otherwise. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - if let int32:Int32 = .init(exactly: self) - { - field.encode(int32: int32) - } - else - { - field.encode(int64: .init(self)) - } - } -} diff --git a/Sources/BSONEncoding/Extensions/Int32 (ext).swift b/Sources/BSONEncoding/Extensions/Int32 (ext).swift deleted file mode 100644 index fda34b0c..00000000 --- a/Sources/BSONEncoding/Extensions/Int32 (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension Int32:BSONEncodable -{ - /// Encodes this integer as a value of type ``BSON.AnyType/int32``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(int32: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/Int64 (ext).swift b/Sources/BSONEncoding/Extensions/Int64 (ext).swift deleted file mode 100644 index 83578959..00000000 --- a/Sources/BSONEncoding/Extensions/Int64 (ext).swift +++ /dev/null @@ -1,11 +0,0 @@ -extension Int64:BSONEncodable -{ - /// Encodes this integer as a value of type ``BSON.AnyType/int64``. It will always use - /// the 64-bit representation, even if it would fit in a ``BSON.AnyType/int32``. To use - /// a variable-length encoding, encode an ``Int`` instead. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(int64: self) - } -} diff --git a/Sources/BSONEncoding/Extensions/Milliseconds (ext).swift b/Sources/BSONEncoding/Extensions/Milliseconds (ext).swift deleted file mode 100644 index 5c8fe3fd..00000000 --- a/Sources/BSONEncoding/Extensions/Milliseconds (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Milliseconds:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Extensions/Minutes (ext).swift b/Sources/BSONEncoding/Extensions/Minutes (ext).swift deleted file mode 100644 index 42867f1f..00000000 --- a/Sources/BSONEncoding/Extensions/Minutes (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Minutes:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Extensions/Never (ext).swift b/Sources/BSONEncoding/Extensions/Never (ext).swift deleted file mode 100644 index 9cd4aa5d..00000000 --- a/Sources/BSONEncoding/Extensions/Never (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension Never:BSONEncodable -{ - /// ``Never`` encodes anything. - @inlinable public - func encode(to _:inout BSON.FieldEncoder) - { - } -} diff --git a/Sources/BSONEncoding/Extensions/Seconds (ext).swift b/Sources/BSONEncoding/Extensions/Seconds (ext).swift deleted file mode 100644 index 45e70cf3..00000000 --- a/Sources/BSONEncoding/Extensions/Seconds (ext).swift +++ /dev/null @@ -1,5 +0,0 @@ -import UnixTime - -extension Seconds:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Extensions/StaticString (ext).swift b/Sources/BSONEncoding/Extensions/StaticString (ext).swift deleted file mode 100644 index 665b0513..00000000 --- a/Sources/BSONEncoding/Extensions/StaticString (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension StaticString:BSONEncodable -{ - /// Encodes this string as a value of type ``BSON.AnyType/string``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(string: .init(self)) - } -} diff --git a/Sources/BSONEncoding/Extensions/String (ext).swift b/Sources/BSONEncoding/Extensions/String (ext).swift deleted file mode 100644 index 2ef456de..00000000 --- a/Sources/BSONEncoding/Extensions/String (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension String:BSONEncodable -{ - /// Encodes this string as a value of type ``BSON.AnyType/string``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(string: BSON.UTF8View.init(self)) - } -} diff --git a/Sources/BSONEncoding/Extensions/Substring (ext).swift b/Sources/BSONEncoding/Extensions/Substring (ext).swift deleted file mode 100644 index c98c92da..00000000 --- a/Sources/BSONEncoding/Extensions/Substring (ext).swift +++ /dev/null @@ -1,9 +0,0 @@ -extension Substring:BSONEncodable -{ - /// Encodes this substring as a value of type ``BSON.AnyType/string``. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(string: BSON.UTF8View.init(self)) - } -} diff --git a/Sources/BSONEncoding/Extensions/Unicode.Scalar (ext).swift b/Sources/BSONEncoding/Extensions/Unicode.Scalar (ext).swift deleted file mode 100644 index 011fac44..00000000 --- a/Sources/BSONEncoding/Extensions/Unicode.Scalar (ext).swift +++ /dev/null @@ -1,8 +0,0 @@ -extension Unicode.Scalar:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self.description.encode(to: &field) - } -} diff --git a/Sources/BSONEncoding/Extensions/UnixMillisecond (ext).swift b/Sources/BSONEncoding/Extensions/UnixMillisecond (ext).swift deleted file mode 100644 index 21349904..00000000 --- a/Sources/BSONEncoding/Extensions/UnixMillisecond (ext).swift +++ /dev/null @@ -1,10 +0,0 @@ -import UnixTime - -extension UnixMillisecond:BSONEncodable -{ - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - field.encode(millisecond: self) - } -} diff --git a/Sources/BSONEncoding/LazyDropWhileSequence (ext).swift b/Sources/BSONEncoding/LazyDropWhileSequence (ext).swift deleted file mode 100644 index 083e762c..00000000 --- a/Sources/BSONEncoding/LazyDropWhileSequence (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension LazyDropWhileSequence:BSONListEncodable, BSONEncodable where Element:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/LazyFilterSequence (ext).swift b/Sources/BSONEncoding/LazyFilterSequence (ext).swift deleted file mode 100644 index b093ab99..00000000 --- a/Sources/BSONEncoding/LazyFilterSequence (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension LazyFilterSequence:BSONListEncodable, BSONEncodable where Element:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/LazyMapSequence (ext).swift b/Sources/BSONEncoding/LazyMapSequence (ext).swift deleted file mode 100644 index 8c351a26..00000000 --- a/Sources/BSONEncoding/LazyMapSequence (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension LazyMapSequence:BSONListEncodable, BSONEncodable where Element:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/LazyPrefixWhileSequence (ext).swift b/Sources/BSONEncoding/LazyPrefixWhileSequence (ext).swift deleted file mode 100644 index 91c1d36b..00000000 --- a/Sources/BSONEncoding/LazyPrefixWhileSequence (ext).swift +++ /dev/null @@ -1,3 +0,0 @@ -extension LazyPrefixWhileSequence:BSONListEncodable, BSONEncodable where Element:BSONEncodable -{ -} diff --git a/Sources/BSONEncoding/Optional (ext).swift b/Sources/BSONEncoding/Optional (ext).swift deleted file mode 100644 index 7e08fed8..00000000 --- a/Sources/BSONEncoding/Optional (ext).swift +++ /dev/null @@ -1,35 +0,0 @@ -extension Optional:BSONEncodable where Wrapped:BSONEncodable -{ - /// Encodes this optional as an explicit ``BSON.AnyType/null``, if nil. - @inlinable public - func encode(to field:inout BSON.FieldEncoder) - { - self?.encode(to: &field) ?? BSON.Null.init().encode(to: &field) - } -} -// These APIs must additionally be extensions on ``Optional`` and not just -// ``BSONEncodable`` because SE-299 does not support protocol extension -// member lookup with unnamed closure parameters. Only the APIs that take -// closure arguments need to be duplicated here. -extension BSON.Document? -{ - @inlinable public - init(_:CodingKey.Type = CodingKey.self, - with populate:(inout BSON.DocumentEncoder) throws -> ()) rethrows - { - self = .some(try .init(with: populate)) - } - @inlinable public - init(with populate:(inout BSON.DocumentEncoder) throws -> ()) rethrows - { - self = .some(try .init(with: populate)) - } -} -extension BSON.List? -{ - @inlinable public - init(with populate:(inout BSON.ListEncoder) throws -> ()) rethrows - { - self = .some(try .init(with: populate)) - } -} diff --git a/Sources/BSONEncoding/README.md b/Sources/BSONEncoding/README.md deleted file mode 100644 index d099ed1f..00000000 --- a/Sources/BSONEncoding/README.md +++ /dev/null @@ -1 +0,0 @@ -# ``/BSONEncoding`` diff --git a/Sources/BSONEncoding/exports.swift b/Sources/BSONEncoding/exports.swift deleted file mode 100644 index 39f8f8b5..00000000 --- a/Sources/BSONEncoding/exports.swift +++ /dev/null @@ -1 +0,0 @@ -@_exported import enum BSONABI.BSON diff --git a/Sources/BSONEncodingTests/Fields/Main.FieldDuplication.swift b/Sources/BSONEncodingTests/Fields/Main.FieldDuplication.swift deleted file mode 100644 index 8abd8af9..00000000 --- a/Sources/BSONEncodingTests/Fields/Main.FieldDuplication.swift +++ /dev/null @@ -1,29 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum FieldDuplication - { - } -} -extension Main.FieldDuplication:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests / "integer", - encoded: .init(BSON.Key.self) - { - $0["inhabited"] = 5 - $0["uninhabited"] = nil as Never?? - $0["inhabited"] = 7 - $0["uninhabited"] = nil as Never?? - }, - literal: - [ - "inhabited": 5, - "inhabited": 7, - ]) - } -} diff --git a/Sources/BSONEncodingTests/Fields/Main.FieldElision.swift b/Sources/BSONEncodingTests/Fields/Main.FieldElision.swift deleted file mode 100644 index c1bf476e..00000000 --- a/Sources/BSONEncodingTests/Fields/Main.FieldElision.swift +++ /dev/null @@ -1,52 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum FieldElision - { - } -} -extension Main.FieldElision:TestBattery -{ - static - func run(tests:TestGroup) - { - let _:BSON.Document = [:] - - Self.run(tests / "null", - encoded: .init(BSON.Key.self) - { - $0["elided"] = nil as Never?? - $0["inhabited"] = BSON.Null.init() - }, - literal: - [ - "inhabited": .null, - ]) - - Self.run(tests / "integer", - encoded: .init(BSON.Key.self) - { - $0["elided"] = nil as Int? - $0["inhabited"] = 5 - }, - literal: - [ - "inhabited": 5, - ]) - - Self.run(tests / "optional", - encoded: .init(BSON.Key.self) - { - $0["elided"] = nil as Int?? - $0["inhabited"] = (5 as Int?) as Int?? - $0["uninhabited"] = (nil as Int?) as Int?? - }, - literal: - [ - "inhabited": 5, - "uninhabited": .null, - ]) - } -} diff --git a/Sources/BSONEncodingTests/Inference/Main.LiteralInference.swift b/Sources/BSONEncodingTests/Inference/Main.LiteralInference.swift deleted file mode 100644 index 1b706e86..00000000 --- a/Sources/BSONEncodingTests/Inference/Main.LiteralInference.swift +++ /dev/null @@ -1,121 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum LiteralInference - { - } -} -extension Main.LiteralInference:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests / "integer", - encoded: .init(BSON.Key.self) - { - $0["default"] = 1 - $0["default-long"] = 0x7fff_ffff_ffff_ffff - $0["int32"] = 1 as Int32 - $0["int64"] = 1 as Int64 - $0["int"] = 1 as Int - $0["int-long"] = 0x7fff_ffff_ffff_ffff as Int - }, - literal: - [ - "default": 1, - "default-long": 0x7fff_ffff_ffff_ffff, - "int32": .int32(1), - "int64": .int64(1), - "int": .int32(1), - "int-long": .int64(0x7fff_ffff_ffff_ffff), - ]) - - Self.run(tests / "floating-point", - encoded: .init(BSON.Key.self) - { - $0["default"] = 1.0 - $0["a"] = 1.0 as Double - }, - literal: - [ - "default": 1.0, - "a": .double(1.0), - ]) - - Self.run(tests / "string", - encoded: .init(BSON.Key.self) - { - $0["a"] = "string" - $0["b"] = "string" - $0["c"] = "string" as BSON.UTF8View - $0["d"] = "string" as BSON.UTF8View - }, - literal: - [ - "a": "string", - "b": "string", - "c": .string(.init(from: "string")), - "d": .string(.init(from: "string")), - ]) - - Self.run(tests / "optionals", - encoded: .init(BSON.Key.self) - { - $0["a"] = [1, nil, 3] - $0["b"] = [1, nil, 3] - $0["c"] = [1, .null, 3] as BSON.List - $0["d"] = [1, .null, 3] as BSON.List - }, - literal: - [ - "a": [1, .null, 3], - "b": .list([1, .null, 3]), - "c": [1, .null, 3], - "d": .list([1, .null, 3]), - ]) - - Self.run(tests / "list", - encoded: .init(BSON.Key.self) - { - $0["a"] = [1, 2, 3] - $0["b"] = [1, 2, 3] - $0["c"] = [1, 2, 3] as BSON.List - $0["d"] = [1, 2, 3] as BSON.List - }, - literal: - [ - "a": [1, 2, 3], - "b": .list([1, 2, 3]), - "c": [1, 2, 3], - "d": .list([1, 2, 3]), - ]) - - Self.run(tests / "document", - encoded: .init(BSON.Key.self) - { - $0["a"](BSON.Key.self) - { - $0["a"] = 1 - $0["b"] = 2 - $0["c"] = 3 - } - $0["b"](BSON.Key.self) - { - $0["a"] = 1 - $0["b"] = 2 - $0["c"] = 3 - } - $0["c"] = ["a": 1, "b": 2, "c": 3] as BSON.Document - $0["d"] = ["a": 1, "b": 2, "c": 3] as BSON.Document - }, - literal: - [ - "a": ["a": 1, "b": 2, "c": 3], - "b": .document(["a": 1, "b": 2, "c": 3]), - "c": ["a": 1, "b": 2, "c": 3], - "d": .document(["a": 1, "b": 2, "c": 3]), - ]) - } -} diff --git a/Sources/BSONEncodingTests/Inference/Main.TypeInference.swift b/Sources/BSONEncodingTests/Inference/Main.TypeInference.swift deleted file mode 100644 index 7efd4b67..00000000 --- a/Sources/BSONEncodingTests/Inference/Main.TypeInference.swift +++ /dev/null @@ -1,57 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum TypeInference - { - } -} -extension Main.TypeInference:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests / "binary", - encoded: .init(BSON.Key.self) - { - $0["a"] = BSON.BinaryView<[UInt8]>.init(subtype: .generic, - bytes: [0xff, 0xff, 0xff]) - }, - literal: - [ - "a": .binary(.init(subtype: .generic, - bytes: [0xff, 0xff, 0xff])), - ]) - - Self.run(tests / "max", - encoded: .init(BSON.Key.self) - { - $0["max"] = BSON.Max.init() - }, - literal: - [ - "max": .max, - ]) - - Self.run(tests / "min", - encoded: .init(BSON.Key.self) - { - $0["min"] = BSON.Min.init() - }, - literal: - [ - "min": .min, - ]) - - Self.run(tests / "null", - encoded: .init(BSON.Key.self) - { - $0["null"] = (nil as Never?) as Never?? - }, - literal: - [ - "null": .null, - ]) - } -} diff --git a/Sources/BSONEncodingTests/Main.EncodeDocument.swift b/Sources/BSONEncodingTests/Main.EncodeDocument.swift deleted file mode 100644 index 7e9e3f3b..00000000 --- a/Sources/BSONEncodingTests/Main.EncodeDocument.swift +++ /dev/null @@ -1,36 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum EncodeDocument - { - } -} -extension Main.EncodeDocument:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests, - encoded: .init(BSON.Key.self) - { - $0["a"] = [:] - $0["b"](BSON.Key.self) - { - $0["x"] = 1 - } - $0["c"](BSON.Key.self) - { - $0["x"] = 1 - $0["y"] = 2 - } - }, - literal: - [ - "a": [:], - "b": ["x": 1], - "c": ["x": 1, "y": 2], - ]) - } -} diff --git a/Sources/BSONEncodingTests/Main.EncodeList.swift b/Sources/BSONEncodingTests/Main.EncodeList.swift deleted file mode 100644 index cc1abeac..00000000 --- a/Sources/BSONEncodingTests/Main.EncodeList.swift +++ /dev/null @@ -1,34 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum EncodeList - { - } -} -extension Main.EncodeList:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests, - encoded: .init(BSON.Key.self) - { - $0["a"] = [] as [Never] - $0["b"] = [1] - $0["c"](Int.self) - { - $0[+] = 1 - $0[+] = "x" - $0[+] = 5.5 - } - }, - literal: - [ - "a": [], - "b": [1], - "c": [1, "x", 5.5], - ]) - } -} diff --git a/Sources/BSONEncodingTests/Main.EncodeString.swift b/Sources/BSONEncodingTests/Main.EncodeString.swift deleted file mode 100644 index 682c28ee..00000000 --- a/Sources/BSONEncodingTests/Main.EncodeString.swift +++ /dev/null @@ -1,29 +0,0 @@ -import BSONEncoding -import Testing_ - -extension Main -{ - enum EncodeString - { - } -} -extension Main.EncodeString:TestBattery -{ - static - func run(tests:TestGroup) - { - Self.run(tests, - encoded: .init(BSON.Key.self) - { - $0["a"] = "" - $0["b"] = "foo" - $0["c"] = "foo\u{0}" - }, - literal: - [ - "a": "", - "b": "foo", - "c": "foo\u{0}", - ]) - } -} diff --git a/Sources/BSONEncodingTests/Main.swift b/Sources/BSONEncodingTests/Main.swift deleted file mode 100644 index 88872810..00000000 --- a/Sources/BSONEncodingTests/Main.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Testing_ - -@main -enum Main:TestMain -{ - static - let all:[any TestBattery.Type] = - [ - LiteralInference.self, - TypeInference.self, - - EncodeDocument.self, - EncodeList.self, - EncodeString.self, - - FieldDuplication.self, - FieldElision.self, - ] -} diff --git a/Sources/BSONEncodingTests/TestBattery (ext).swift b/Sources/BSONEncodingTests/TestBattery (ext).swift deleted file mode 100644 index f2742b3d..00000000 --- a/Sources/BSONEncodingTests/TestBattery (ext).swift +++ /dev/null @@ -1,32 +0,0 @@ -import BSONEncoding -import Testing_ - -extension TestBattery -{ - static - func run(_ tests:TestGroup?, - encoded:BSON.Document, - literal:BSON.Document) - { - guard - let tests:TestGroup - else - { - return - } - - tests.expect(encoded ==? literal) - - guard let encoded:[(key:BSON.Key, value:BSON.AnyValue)] = - tests.do({ try encoded.parse { ($0, $1) } }), - let literal:[(key:BSON.Key, value:BSON.AnyValue)] = - tests.do({ try literal.parse { ($0, $1) } }) - else - { - return - } - - tests.expect(encoded.map(\.key) ..? literal.map(\.key)) - tests.expect(encoded.map(\.value) ..? literal.map(\.value)) - } -} diff --git a/Sources/BSONIntegrationTests/Main.EnumeratedCodingKeys.swift b/Sources/BSONIntegrationTests/Main.EnumeratedCodingKeys.swift deleted file mode 100644 index 6229644b..00000000 --- a/Sources/BSONIntegrationTests/Main.EnumeratedCodingKeys.swift +++ /dev/null @@ -1,80 +0,0 @@ -import BSON -import BSONReflection -import Testing_ - -extension Main -{ - enum EnumeratedCodingKeys - { - } -} -extension Main.EnumeratedCodingKeys:TestBattery -{ - static - func run(tests:TestGroup) - { - struct Codable:BSONDocumentDecodable, BSONDocumentEncodable, Equatable - { - enum CodingKey:String, Sendable - { - case a - case b - case c - } - - let a:Int - let b:[Int] - let c:[[Int]] - - init(a:Int, b:[Int], c:[[Int]]) - { - self.a = a - self.b = b - self.c = c - } - - init(bson:BSON.DocumentDecoder) - throws - { - self.a = try bson[.a].decode() - self.b = try bson[.b].decode() - self.c = try bson[.c].decode() - } - - func encode(to bson:inout BSON.DocumentEncoder) - { - bson[.a] = self.a - bson[.b] = self.b - bson[.c] = self.c - } - } - - let expected:Codable = .init(a: 5, b: [5, 6], c: [[5, 6, 7], [8]]) - let bson:BSON.Document = .init(BSON.Key.self) - { - $0["a"] = 5 - $0["b"] = [5, 6] - $0["c"] = [[5, 6, 7], [8]] - $0["d"] = [[[5, 6, 7, 8], [9, 10]], [[11]]] - } - - tests.do - { - let decoded:Codable = try .init(bson: bson) - - tests.expect(decoded ==? expected) - - let encoded:BSON.Document = .init(with: decoded.encode(to:)) - - tests.expect(true: encoded.bytes.count < bson.bytes.count) - - let redecoded:Codable = try .init(bson: encoded) - - tests.expect(redecoded ==? expected) - - let reencoded:BSON.Document = .init(with: redecoded.encode(to:)) - - tests.expect(reencoded.bytes ..? encoded.bytes) - } - } -} diff --git a/Sources/BSONIntegrationTests/Main.swift b/Sources/BSONIntegrationTests/Main.swift deleted file mode 100644 index 2ea678ac..00000000 --- a/Sources/BSONIntegrationTests/Main.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Testing_ - -@main -enum Main:TestMain -{ - static - let all:[any TestBattery.Type] = [EnumeratedCodingKeys.self] -} diff --git a/Sources/BSONLegacy/BSON.AnyValue (ext).swift b/Sources/BSONLegacy/BSON.AnyValue (ext).swift deleted file mode 100644 index b9c9809f..00000000 --- a/Sources/BSONLegacy/BSON.AnyValue (ext).swift +++ /dev/null @@ -1,32 +0,0 @@ -import BSON - -extension BSON.AnyValue:Decoder -{ - @inlinable public - var codingPath:[any CodingKey] - { - [] - } - @inlinable public - var userInfo:[CodingUserInfoKey: Any] - { - [:] - } - - @inlinable public - func singleValueContainer() -> any SingleValueDecodingContainer - { - BSON.SingleValueDecoder.init(self, path: []) as any SingleValueDecodingContainer - } - @inlinable public - func unkeyedContainer() throws -> any UnkeyedDecodingContainer - { - try BSON.SingleValueDecoder.init(self, path: []).unkeyedContainer() - } - @inlinable public - func container(keyedBy _:Key.Type) throws -> KeyedDecodingContainer - where Key:CodingKey - { - try BSON.SingleValueDecoder.init(self, path: []).container(keyedBy: Key.self) - } -} diff --git a/Sources/BSONLegacy/BSON.KeyedDecoder.Super.swift b/Sources/BSONLegacy/BSON.KeyedDecoder.Super.swift deleted file mode 100644 index 237266a7..00000000 --- a/Sources/BSONLegacy/BSON.KeyedDecoder.Super.swift +++ /dev/null @@ -1,9 +0,0 @@ -import BSON - -extension BSON.KeyedDecoder -{ - enum Super:String, CodingKey - { - case `super` - } -} diff --git a/Sources/BSONLegacy/BSON.KeyedDecoder.swift b/Sources/BSONLegacy/BSON.KeyedDecoder.swift deleted file mode 100644 index bc05b02a..00000000 --- a/Sources/BSONLegacy/BSON.KeyedDecoder.swift +++ /dev/null @@ -1,183 +0,0 @@ -import BSON - -extension BSON -{ - struct KeyedDecoder where Key:CodingKey - { - let codingPath:[any CodingKey] - let allKeys:[Key] - let items:BSON.DocumentDecoder - - init(_ dictionary:BSON.DocumentDecoder, - path:[any CodingKey]) - { - self.codingPath = path - self.items = dictionary - self.allKeys = self.items.compactMap { .init(stringValue: $0.key.rawValue) } - } - } -} -extension BSON.KeyedDecoder -{ - // local `Key` type may be different from the dictionary’s `Key` type - func diagnose(_ key:some CodingKey, - _ decode:(BSON.AnyValue) throws -> T?) throws -> T - { - var path:[any CodingKey] - { - self.codingPath + CollectionOfOne.init(key) - } - guard let value:BSON.AnyValue = self.items[.init(key)]?.value - else - { - let context:DecodingError.Context = .init(codingPath: path, - debugDescription: "key '\(key)' not found") - throw DecodingError.keyNotFound(key, context) - } - do - { - if let decoded:T = try decode(value) - { - return decoded - } - - throw DecodingError.init(annotating: BSON.TypecastError.init( - invalid: value.type), - initializing: T.self, - path: path) - } - catch let error - { - throw DecodingError.init(annotating: error, - initializing: T.self, - path: path) - } - } -} - -extension BSON.KeyedDecoder:KeyedDecodingContainerProtocol -{ - public - func contains(_ key:Key) -> Bool - { - self.items.contains(.init(key)) - } - - public - func decode(_:T.Type, forKey key:Key) throws -> T where T:Decodable - { - try .init(from: try self.singleValueContainer(forKey: key)) - } - func decodeNil(forKey key:Key) throws -> Bool - { - try self.diagnose(key) { $0.as(BSON.Null.self) != nil } - } - public - func decode(_:Bool.Type, forKey key:Key) throws -> Bool - { - try self.diagnose(key) { $0.as(Bool.self) } - } - public - func decode(_:Float.Type, forKey key:Key) throws -> Float - { - try self.diagnose(key) { $0.as(Float.self) } - } - public - func decode(_:Double.Type, forKey key:Key) throws -> Double - { - try self.diagnose(key) { $0.as(Double.self) } - } - public - func decode(_:String.Type, forKey key:Key) throws -> String - { - try self.diagnose(key) { $0.as(String.self) } - } - public - func decode(_:Int.Type, forKey key:Key) throws -> Int - { - try self.diagnose(key) { try $0.as(Int.self) } - } - public - func decode(_:Int64.Type, forKey key:Key) throws -> Int64 - { - try self.diagnose(key) { try $0.as(Int64.self) } - } - public - func decode(_:Int32.Type, forKey key:Key) throws -> Int32 - { - try self.diagnose(key) { try $0.as(Int32.self) } - } - public - func decode(_:Int16.Type, forKey key:Key) throws -> Int16 - { - try self.diagnose(key) { try $0.as(Int16.self) } - } - public - func decode(_:Int8.Type, forKey key:Key) throws -> Int8 - { - try self.diagnose(key) { try $0.as(Int8.self) } - } - public - func decode(_:UInt.Type, forKey key:Key) throws -> UInt - { - try self.diagnose(key) { try $0.as(UInt.self) } - } - public - func decode(_:UInt64.Type, forKey key:Key) throws -> UInt64 - { - try self.diagnose(key) { try $0.as(UInt64.self) } - } - public - func decode(_:UInt32.Type, forKey key:Key) throws -> UInt32 - { - try self.diagnose(key) { try $0.as(UInt32.self) } - } - public - func decode(_:UInt16.Type, forKey key:Key) throws -> UInt16 - { - try self.diagnose(key) { try $0.as(UInt16.self) } - } - public - func decode(_:UInt8.Type, forKey key:Key) throws -> UInt8 - { - try self.diagnose(key) { try $0.as(UInt8.self) } - } - - func superDecoder() throws -> any Decoder - { - try self.singleValueContainer(forKey: Super.super, typed: Super.self) - } - public - func superDecoder(forKey key:Key) throws -> any Decoder - { - try self.singleValueContainer(forKey: key) as any Decoder - } - - public - func singleValueContainer(forKey key:T, - typed _:T.Type = T.self) throws -> BSON.SingleValueDecoder - where T:CodingKey - { - let value:BSON.AnyValue = try self.diagnose(key){ $0 } - let decoder:BSON.SingleValueDecoder = .init(value, - path: self.codingPath + CollectionOfOne.init(key)) - return decoder - } - public - func nestedUnkeyedContainer(forKey key:Key) throws -> any UnkeyedDecodingContainer - { - let path:[any CodingKey] = self.codingPath + CollectionOfOne.init(key) - let container:BSON.UnkeyedDecoder = - .init(try self.diagnose(key) { try .init(parsing: $0) }, path: path) - return container as any UnkeyedDecodingContainer - } - public - func nestedContainer(keyedBy _:NestedKey.Type, - forKey key:Key) throws -> KeyedDecodingContainer - { - let path:[any CodingKey] = self.codingPath + CollectionOfOne.init(key) - let container:BSON.KeyedDecoder = - .init(try self.diagnose(key) { try .init(parsing: $0) }, path: path) - return .init(container) - } -} diff --git a/Sources/BSONLegacy/BSON.SingleValueDecoder.swift b/Sources/BSONLegacy/BSON.SingleValueDecoder.swift deleted file mode 100644 index 260086a0..00000000 --- a/Sources/BSONLegacy/BSON.SingleValueDecoder.swift +++ /dev/null @@ -1,156 +0,0 @@ -import BSON - -extension BSON -{ - /// A single-value decoding container, for use with compiler-generated ``Decodable`` - /// implementations. - public - struct SingleValueDecoder - { - let value:BSON.AnyValue - public - let codingPath:[any CodingKey] - public - let userInfo:[CodingUserInfoKey: Any] - - public - init(_ value:BSON.AnyValue, - path:[any CodingKey], - userInfo:[CodingUserInfoKey: Any] = [:]) - { - self.value = value - self.codingPath = path - self.userInfo = userInfo - } - } -} -extension BSON.SingleValueDecoder -{ - func diagnose(_ decode:(BSON.AnyValue) throws -> T?) throws -> T - { - do - { - if let decoded:T = try decode(value) - { - return decoded - } - - throw DecodingError.init(annotating: BSON.TypecastError.init( - invalid: value.type), - initializing: T.self, - path: self.codingPath) - } - catch let error - { - throw DecodingError.init(annotating: error, - initializing: T.self, - path: self.codingPath) - } - } -} -extension BSON.SingleValueDecoder:Decoder -{ - public - func singleValueContainer() -> any SingleValueDecodingContainer - { - self as any SingleValueDecodingContainer - } - public - func unkeyedContainer() throws -> any UnkeyedDecodingContainer - { - BSON.UnkeyedDecoder.init(try self.diagnose { try .init(parsing: $0) }, - path: self.codingPath) as any UnkeyedDecodingContainer - } - public - func container(keyedBy _:Key.Type) throws -> KeyedDecodingContainer - where Key:CodingKey - { - let container:BSON.KeyedDecoder = - .init(try self.diagnose { try .init(parsing: $0) }, path: self.codingPath) - return .init(container) - } -} - -extension BSON.SingleValueDecoder:SingleValueDecodingContainer -{ - public - func decode(_:T.Type) throws -> T where T:Decodable - { - try .init(from: self) - } - public - func decodeNil() -> Bool - { - self.value.as(BSON.Null.self) != nil - } - public - func decode(_:Bool.Type) throws -> Bool - { - try self.diagnose { $0.as(Bool.self) } - } - public - func decode(_:Float.Type) throws -> Float - { - try self.diagnose { $0.as(Float.self) } - } - public - func decode(_:Double.Type) throws -> Double - { - try self.diagnose { $0.as(Double.self) } - } - public - func decode(_:String.Type) throws -> String - { - try self.diagnose { $0.as(String.self) } - } - public - func decode(_:Int.Type) throws -> Int - { - try self.diagnose { try $0.as(Int.self) } - } - public - func decode(_:Int64.Type) throws -> Int64 - { - try self.diagnose { try $0.as(Int64.self) } - } - public - func decode(_:Int32.Type) throws -> Int32 - { - try self.diagnose { try $0.as(Int32.self) } - } - public - func decode(_:Int16.Type) throws -> Int16 - { - try self.diagnose { try $0.as(Int16.self) } - } - public - func decode(_:Int8.Type) throws -> Int8 - { - try self.diagnose { try $0.as(Int8.self) } - } - public - func decode(_:UInt.Type) throws -> UInt - { - try self.diagnose { try $0.as(UInt.self) } - } - public - func decode(_:UInt64.Type) throws -> UInt64 - { - try self.diagnose { try $0.as(UInt64.self) } - } - public - func decode(_:UInt32.Type) throws -> UInt32 - { - try self.diagnose { try $0.as(UInt32.self) } - } - public - func decode(_:UInt16.Type) throws -> UInt16 - { - try self.diagnose { try $0.as(UInt16.self) } - } - public - func decode(_:UInt8.Type) throws -> UInt8 - { - try self.diagnose { try $0.as(UInt8.self) } - } -} diff --git a/Sources/BSONLegacy/BSON.UnkeyedDecoder.Index.swift b/Sources/BSONLegacy/BSON.UnkeyedDecoder.Index.swift deleted file mode 100644 index df138f61..00000000 --- a/Sources/BSONLegacy/BSON.UnkeyedDecoder.Index.swift +++ /dev/null @@ -1,31 +0,0 @@ -import BSON - -extension BSON.UnkeyedDecoder -{ - struct Index:CodingKey - { - let value:Int - var intValue:Int? - { - self.value - } - var stringValue:String - { - "\(self.value)" - } - - init(intValue:Int) - { - self.value = intValue - } - init?(stringValue:String) - { - guard let value:Int = Int.init(stringValue) - else - { - return nil - } - self.value = value - } - } -} diff --git a/Sources/BSONLegacy/BSON.UnkeyedDecoder.swift b/Sources/BSONLegacy/BSON.UnkeyedDecoder.swift deleted file mode 100644 index 6dc6aedd..00000000 --- a/Sources/BSONLegacy/BSON.UnkeyedDecoder.swift +++ /dev/null @@ -1,190 +0,0 @@ -import BSON - -extension BSON -{ - struct UnkeyedDecoder - { - public - let codingPath:[any CodingKey] - public - var currentIndex:Int - let elements:[BSON.AnyValue] - - public - init(_ array:BSON.ListDecoder, path:[any CodingKey]) - { - self.codingPath = path - self.elements = array.elements - self.currentIndex = self.elements.startIndex - } - } -} -extension BSON.UnkeyedDecoder -{ - public - var count:Int? - { - self.elements.count - } - public - var isAtEnd:Bool - { - self.currentIndex >= self.elements.endIndex - } - - mutating - func diagnose(_ decode:(BSON.AnyValue) throws -> T?) throws -> T - { - let key:Index = .init(intValue: self.currentIndex) - var path:[any CodingKey] - { - self.codingPath + CollectionOfOne.init(key) - } - - if self.isAtEnd - { - let context:DecodingError.Context = .init(codingPath: path, - debugDescription: "index (\(self.currentIndex)) out of range") - throw DecodingError.keyNotFound(key, context) - } - - let value:BSON.AnyValue = self.elements[self.currentIndex] - self.currentIndex += 1 - do - { - if let decoded:T = try decode(value) - { - return decoded - } - - throw DecodingError.init(annotating: BSON.TypecastError.init( - invalid: value.type), - initializing: T.self, - path: path) - } - catch let error - { - throw DecodingError.init(annotating: error, - initializing: T.self, - path: path) - } - } -} - -extension BSON.UnkeyedDecoder:UnkeyedDecodingContainer -{ - public mutating - func decode(_:T.Type) throws -> T where T:Decodable - { - try .init(from: try self.singleValueContainer()) - } - public mutating - func decodeNil() throws -> Bool - { - try self.diagnose { $0.as(BSON.Null.self) != nil } - } - public mutating - func decode(_:Bool.Type) throws -> Bool - { - try self.diagnose { $0.as(Bool.self) } - } - public mutating - func decode(_:Float.Type) throws -> Float - { - try self.diagnose { $0.as(Float.self) } - } - public mutating - func decode(_:Double.Type) throws -> Double - { - try self.diagnose { $0.as(Double.self) } - } - public mutating - func decode(_:String.Type) throws -> String - { - try self.diagnose { $0.as(String.self) } - } - public mutating - func decode(_:Int.Type) throws -> Int - { - try self.diagnose { try $0.as(Int.self) } - } - public mutating - func decode(_:Int64.Type) throws -> Int64 - { - try self.diagnose { try $0.as(Int64.self) } - } - public mutating - func decode(_:Int32.Type) throws -> Int32 - { - try self.diagnose { try $0.as(Int32.self) } - } - public mutating - func decode(_:Int16.Type) throws -> Int16 - { - try self.diagnose { try $0.as(Int16.self) } - } - public mutating - func decode(_:Int8.Type) throws -> Int8 - { - try self.diagnose { try $0.as(Int8.self) } - } - public mutating - func decode(_:UInt.Type) throws -> UInt - { - try self.diagnose { try $0.as(UInt.self) } - } - public mutating - func decode(_:UInt64.Type) throws -> UInt64 - { - try self.diagnose { try $0.as(UInt64.self) } - } - public mutating - func decode(_:UInt32.Type) throws -> UInt32 - { - try self.diagnose { try $0.as(UInt32.self) } - } - public mutating - func decode(_:UInt16.Type) throws -> UInt16 - { - try self.diagnose { try $0.as(UInt16.self) } - } - public mutating - func decode(_:UInt8.Type) throws -> UInt8 - { - try self.diagnose { try $0.as(UInt8.self) } - } - - public mutating - func superDecoder() throws -> any Decoder - { - try self.singleValueContainer() as any Decoder - } - public mutating - func singleValueContainer() throws -> BSON.SingleValueDecoder - { - let key:Index = .init(intValue: self.currentIndex) - let value:BSON.AnyValue = try self.diagnose { $0 } - let decoder:BSON.SingleValueDecoder = .init(value, - path: self.codingPath + CollectionOfOne.init(key)) - return decoder - } - public mutating - func nestedUnkeyedContainer() throws -> any UnkeyedDecodingContainer - { - let path:[any CodingKey] = self.codingPath + - CollectionOfOne.init(Index.init(intValue: self.currentIndex)) - let container:BSON.UnkeyedDecoder = - .init(try self.diagnose { try .init(parsing: $0) }, path: path) - return container as any UnkeyedDecodingContainer - } - public mutating - func nestedContainer(keyedBy _:NestedKey.Type) - throws -> KeyedDecodingContainer - { - let path:[any CodingKey] = self.codingPath + - CollectionOfOne.init(Index.init(intValue: self.currentIndex)) - let container:BSON.KeyedDecoder = - .init(try self.diagnose { try .init(parsing: $0) }, path: path) - return .init(container) - } -} diff --git a/Sources/BSONLegacy/DecodingError (ext).swift b/Sources/BSONLegacy/DecodingError (ext).swift deleted file mode 100644 index c99eaa46..00000000 --- a/Sources/BSONLegacy/DecodingError (ext).swift +++ /dev/null @@ -1,14 +0,0 @@ -extension DecodingError -{ - init(annotating error:any Error, initializing _:T.Type, path:[any CodingKey]) - { - let description:String = - """ - initializer for type '\(String.init(reflecting: T.self))' \ - threw an error while validating bson value at coding path \(path) - """ - let context:DecodingError.Context = .init(codingPath: path, - debugDescription: description, underlyingError: error) - self = .dataCorrupted(context) - } -} diff --git a/Sources/BSONReflection/BSON.AnyValue (ext).swift b/Sources/BSONReflection/BSON.AnyValue (ext).swift deleted file mode 100644 index 97ff3386..00000000 --- a/Sources/BSONReflection/BSON.AnyValue (ext).swift +++ /dev/null @@ -1,164 +0,0 @@ -import BSON -import UnixTime - -extension BSON.AnyValue -{ - func description(indent:BSON.Indent) -> String - { - switch self - { - case .document(let document): - document.description(indent: indent) - case .list(let list): - list.description(indent: indent) - case .binary(let binary): - "{ binary data, type \(binary.subtype.rawValue) }" - case .bool(let bool): - "\(bool)" - case .decimal128(let decimal128): - "\(decimal128) as BSON.Decimal128" - case .double(let double): - "\(double)" - case .id(let id): - "\(id)" - case .int32(let int32): - "\(int32)" - case .int64(let int64): - "\(int64) as Int64" - case .javascript(let javascript): - "'\(javascript)'" - case .javascriptScope(_, _): - "{ javascript with scope }" - case .max: - "max" - case .millisecond(let millisecond): - "\(millisecond.index) as UnixMillisecond" - case .min: - "min" - case .null: - "null" - case .pointer(let database, let id): - "\(database) + \(id)" - case .regex(let regex): - "\(regex)" - case .string(let utf8): - "\"\(utf8)\"" - case .timestamp(let timestamp): - "\(timestamp)" - } - } -} -extension BSON.AnyValue:CustomStringConvertible -{ - public - var description:String { self.description(indent: " ") } -} -extension BSON.AnyValue -{ - /// Performs a type-aware equivalence comparison. - /// If both operands are a ``document(_:)`` (or ``list(_:)``), performs a recursive - /// type-aware comparison by calling `BSON//DocumentView.~~(_:_:)`. - /// If both operands are a ``string(_:)``, performs unicode-aware string comparison. - /// If both operands are a ``double(_:)``, performs floating-point-aware - /// numerical comparison. - /// - /// > Warning: - /// Comparison of ``decimal128(_:)`` values uses bitwise equality. This library does - /// not support decimal equivalence. - /// - /// > Warning: - /// Comparison of ``millisecond(_:)`` values uses integer equality. This library does - /// not support calendrical equivalence. - /// - /// > Note: - /// The embedded document in the deprecated `javascriptScope(_:_:)` variant - /// also receives type-aware treatment. - /// - /// > Note: - /// The embedded UTF-8 string in the deprecated `pointer(_:_:)` variant - /// also receives type-aware treatment. - @inlinable public static - func ~~ (lhs:Self, rhs:BSON.AnyValue) -> Bool - { - switch (lhs, rhs) - { - case (.document (let lhs), .document (let rhs)): - lhs ~~ rhs - case (.list (let lhs), .list (let rhs)): - lhs ~~ rhs - case (.binary (let lhs), .binary (let rhs)): - lhs == rhs - case (.bool (let lhs), .bool (let rhs)): - lhs == rhs - case (.decimal128 (let lhs), .decimal128 (let rhs)): - lhs == rhs - case (.double (let lhs), .double (let rhs)): - lhs == rhs - case (.id (let lhs), .id (let rhs)): - lhs == rhs - case (.int32 (let lhs), .int32 (let rhs)): - lhs == rhs - case (.int64 (let lhs), .int64 (let rhs)): - lhs == rhs - case (.javascript (let lhs), .javascript (let rhs)): - lhs == rhs - case (.javascriptScope(let lhs, let lhsCode), .javascriptScope(let rhs, let rhsCode)): - lhsCode == rhsCode && lhs ~~ rhs - case (.max, .max): - true - case (.millisecond (let lhs), .millisecond (let rhs)): - lhs.index == rhs.index - case (.min, .min): - true - case (.null, .null): - true - case (.pointer(let lhs, let lhsID), .pointer(let rhs, let rhsID)): - lhsID == rhsID && lhs == rhs - case (.regex (let lhs), .regex (let rhs)): - lhs == rhs - case (.string (let lhs), .string (let rhs)): - lhs == rhs - case (.timestamp (let lhs), .timestamp (let rhs)): - lhs == rhs - - default: - false - } - } -} -extension BSON.AnyValue -{ - /// Recursively parses and re-encodes any embedded documents (and list-documents) - /// in this variant value. - @inlinable public - func canonicalized() throws -> Self - { - switch self - { - case .document(let document): - .document(try document.canonicalized()) - case .list(let list): - .list(try list.canonicalized()) - case .binary, - .bool, - .decimal128, - .double, - .id, - .int32, - .int64, - .javascript: - self - case .javascriptScope(let scope, let utf8): - .javascriptScope(try scope.canonicalized(), utf8) - case .max, - .millisecond, - .min, - .null, - .pointer, - .regex, - .string, - .timestamp: - self - } - } -} diff --git a/Sources/BSONReflection/BSON.Document (ext).swift b/Sources/BSONReflection/BSON.Document (ext).swift deleted file mode 100644 index 7fa64dbb..00000000 --- a/Sources/BSONReflection/BSON.Document (ext).swift +++ /dev/null @@ -1,81 +0,0 @@ -import BSON - -extension BSON.Document -{ - func description(indent:BSON.Indent) -> String - { - if self.isEmpty - { - return "[:]" - } - do - { - var string:String = indent.level == 0 ? "{" : "\(indent){" - try self.parse - { - (indent + 1).print(key: $0, value: $1, to: &string) - } - string += "\(indent)}" - return string - } - catch - { - return "{ corrupted }" - } - } -} -extension BSON.Document:CustomStringConvertible -{ - public - var description:String { self.description(indent: " ") } -} -extension BSON.Document -{ - /// Performs a type-aware equivalence comparison by parsing each operand and recursively - /// comparing the elements. Returns false if either operand fails to parse. - /// - /// Some documents that do not compare equal under byte-wise - /// `==` comparison may compare equal under this operator, due to normalization - /// of deprecated BSON variants. For example, a value of the deprecated `symbol` type - /// will compare equal to a ``BSON.AnyValue/string(_:)`` value with the same contents. - @inlinable public static - func ~~ (lhs:Self, rhs:Self) -> Bool - { - if let lhs:[(key:BSON.Key, value:BSON.AnyValue)] = - try? lhs.parse({ ($0, $1) }), - let rhs:[(key:BSON.Key, value:BSON.AnyValue)] = - try? rhs.parse({ ($0, $1) }), - rhs.count == lhs.count - { - for (lhs, rhs): - ( - (key:BSON.Key, value:BSON.AnyValue), - (key:BSON.Key, value:BSON.AnyValue) - ) - in zip(lhs, rhs) - { - guard lhs.key == rhs.key, - lhs.value ~~ rhs.value - else - { - return false - } - } - return true - } - else - { - return false - } - } -} -extension BSON.Document -{ - /// Recursively parses and re-encodes this document, and any embedded documents - /// (and list-documents) in its elements. The keys will not be changed or re-ordered. - @inlinable public - func canonicalized() throws -> Self - { - .init(fields: try self.parse { ($0, try $1.canonicalized()) }) - } -} diff --git a/Sources/BSONReflection/BSON.Indent.swift b/Sources/BSONReflection/BSON.Indent.swift deleted file mode 100644 index df3e89b4..00000000 --- a/Sources/BSONReflection/BSON.Indent.swift +++ /dev/null @@ -1,57 +0,0 @@ -import BSON - -extension BSON -{ - @frozen public - struct Indent - { - public - let space:String - public - let level:Int - - @inlinable public - init(space:String, level:Int) - { - self.space = space - self.level = level - } - } -} -extension BSON.Indent -{ - @inlinable public static - func + (self:Self, increment:Int) -> Self - { - .init(space: self.space, level: self.level + increment) - } -} -extension BSON.Indent:ExpressibleByStringLiteral -{ - @inlinable public - init(stringLiteral:String) - { - self.init(space: stringLiteral, level: 0) - } -} -extension BSON.Indent:CustomStringConvertible -{ - @inlinable public - var description:String { "\n\(String.init(repeating: space, count: level))" } -} -extension BSON.Indent -{ - public - func print(key:BSON.Key, value:BSON.AnyValue, to output:inout some TextOutputStream) - { - output.write("\(self)$0[\(key)] =") - - let value:String = value.description(indent: self) - // Don’t generate lines with trailing whitespace - if case false = value.first?.isNewline - { - output.write(" ") - } - output.write(value) - } -} diff --git a/Sources/BSONReflection/BSON.List (ext).swift b/Sources/BSONReflection/BSON.List (ext).swift deleted file mode 100644 index 874953aa..00000000 --- a/Sources/BSONReflection/BSON.List (ext).swift +++ /dev/null @@ -1,57 +0,0 @@ -import BSON - -extension BSON.List -{ - func description(indent:BSON.Indent) -> String - { - self.isEmpty ? "[]" : BSON.Document.init(list: self).description(indent: indent) - } -} -extension BSON.List:CustomStringConvertible -{ - public - var description:String { self.description(indent: " ") } -} -extension BSON.List -{ - /// Performs a type-aware equivalence comparison by parsing each operand and recursively - /// comparing the elements, ignoring list key names. Returns `false` if either - /// operand fails to parse. - /// - /// Some embedded documents that do not compare equal under byte-wise - /// `==` comparison may also compare equal under this operator, due to normalization - /// of deprecated BSON variants. For example, a value of the deprecated `symbol` type - /// will compare equal to a `BSON//Value.string(_:)` value with the same contents. - @inlinable public static - func ~~ (lhs:Self, rhs:Self) -> Bool - { - if let lhs:[BSON.AnyValue] = try? lhs.parse(), - let rhs:[BSON.AnyValue] = try? rhs.parse(), - rhs.count == lhs.count - { - for (lhs, rhs):(BSON.AnyValue, BSON.AnyValue) in zip(lhs, rhs) - { - guard lhs ~~ rhs - else - { - return false - } - } - return true - } - else - { - return false - } - } -} -extension BSON.List -{ - /// Recursively parses and re-encodes this list-document, and any embedded documents - /// (and list-documents) in its elements. The ordinal keys will be regenerated. - @inlinable public - func canonicalized() throws -> Self - { - .init(elements: try self.parse { try $0.canonicalized() }) - } -} diff --git a/Sources/BSONReflection/lexemes.swift b/Sources/BSONReflection/lexemes.swift deleted file mode 100644 index 93049e8a..00000000 --- a/Sources/BSONReflection/lexemes.swift +++ /dev/null @@ -1 +0,0 @@ -infix operator ~~ : ComparisonPrecedence diff --git a/Sources/BSONReflectionTests/Main.Documents.swift b/Sources/BSONReflectionTests/Main.Documents.swift deleted file mode 100644 index 29f3c634..00000000 --- a/Sources/BSONReflectionTests/Main.Documents.swift +++ /dev/null @@ -1,256 +0,0 @@ -import BSON -import BSONReflection -import Testing_ - -extension Main -{ - enum Documents - { - } -} -extension Main.Documents:TestBattery -{ - static - func run(tests:TestGroup) - { - let document:BSON.Document = .init(BSON.Key.self) - { - $0["_id"] = 0x1111_2222_3333_4444_5555_6666 as BSON.Identifier - $0["facility"] = "Recreation and Activities Center" - - $0["logo"] = BSON.BinaryView<[UInt8]>.init( - subtype: .generic, - bytes: [1, 2, 3, 4, 5]) - - $0["incidents"] = 145 - $0["averageRating"] = 2.76 - $0["supervisors"] = ["Barbie", "Midge", "Raquelle"] - $0["notes"] = [] as [Never] - $0["campaigns"] = [:] - $0["complaints"](Int.self) - { - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AABB - $0["type"] = "property damage" - $0["supervisor"] = "Raquelle" - $0["status"] = "open" - $0["date"](BSON.Key.self) - { - $0["Y"] = 2022 - $0["M"] = 12 - $0["D"] = 31 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AABC - $0["type"] = "sexual assault" - $0["supervisor"] = "Midge" - $0["status"] = "open" - $0["rpi"] = true - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 1 - $0["D"] = 1 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AABD - $0["type"] = "property theft" - $0["supervisor"] = "Barbie" - $0["status"] = "closed" - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 1 - $0["D"] = 4 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AABE - $0["type"] = "property damage" - $0["supervisor"] = "Midge" - $0["status"] = "open" - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 1 - $0["D"] = 16 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AABF - $0["type"] = "assault" - $0["supervisor"] = "Raquelle" - $0["status"] = "closed" - $0["rpi"] = false - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 1 - $0["D"] = 22 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AAC0 - $0["type"] = "guest expulsion" - $0["supervisor"] = "Barbie" - $0["status"] = "closed" - $0["rpi"] = true - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 2 - $0["D"] = 14 - } - } - $0(BSON.Key.self) - { - $0["_id"] = 0x4455_6677_8899_AAC1 - $0["type"] = "sexual assault" - $0["supervisor"] = "Barbie" - $0["status"] = "open" - $0["rpi"] = false - $0["date"](BSON.Key.self) - { - $0["Y"] = 2023 - $0["M"] = 2 - $0["D"] = 14 - } - } - } - } - let value:BSON.AnyValue = .document(document) - let expected:String = - """ - { - $0[_id] = 0x11112222_33334444_55556666 - $0[facility] = "Recreation and Activities Center" - $0[logo] = { binary data, type 0 } - $0[incidents] = 145 - $0[averageRating] = 2.76 - $0[supervisors] = - { - $0[0] = "Barbie" - $0[1] = "Midge" - $0[2] = "Raquelle" - } - $0[notes] = [] - $0[campaigns] = [:] - $0[complaints] = - { - $0[0] = - { - $0[_id] = 4923954431178418875 as Int64 - $0[type] = "property damage" - $0[supervisor] = "Raquelle" - $0[status] = "open" - $0[date] = - { - $0[Y] = 2022 - $0[M] = 12 - $0[D] = 31 - } - } - $0[1] = - { - $0[_id] = 4923954431178418876 as Int64 - $0[type] = "sexual assault" - $0[supervisor] = "Midge" - $0[status] = "open" - $0[rpi] = true - $0[date] = - { - $0[Y] = 2023 - $0[M] = 1 - $0[D] = 1 - } - } - $0[2] = - { - $0[_id] = 4923954431178418877 as Int64 - $0[type] = "property theft" - $0[supervisor] = "Barbie" - $0[status] = "closed" - $0[date] = - { - $0[Y] = 2023 - $0[M] = 1 - $0[D] = 4 - } - } - $0[3] = - { - $0[_id] = 4923954431178418878 as Int64 - $0[type] = "property damage" - $0[supervisor] = "Midge" - $0[status] = "open" - $0[date] = - { - $0[Y] = 2023 - $0[M] = 1 - $0[D] = 16 - } - } - $0[4] = - { - $0[_id] = 4923954431178418879 as Int64 - $0[type] = "assault" - $0[supervisor] = "Raquelle" - $0[status] = "closed" - $0[rpi] = false - $0[date] = - { - $0[Y] = 2023 - $0[M] = 1 - $0[D] = 22 - } - } - $0[5] = - { - $0[_id] = 4923954431178418880 as Int64 - $0[type] = "guest expulsion" - $0[supervisor] = "Barbie" - $0[status] = "closed" - $0[rpi] = true - $0[date] = - { - $0[Y] = 2023 - $0[M] = 2 - $0[D] = 14 - } - } - $0[6] = - { - $0[_id] = 4923954431178418881 as Int64 - $0[type] = "sexual assault" - $0[supervisor] = "Barbie" - $0[status] = "open" - $0[rpi] = false - $0[date] = - { - $0[Y] = 2023 - $0[M] = 2 - $0[D] = 14 - } - } - } - } - """ - - var l:Int = 0 - for (line, expected):(Substring, Substring) in zip( - "\(value)".split(whereSeparator: \.isNewline), - expected.split(whereSeparator: \.isNewline)) - { - l += 1 - (tests / "Line\(l)")?.expect(line ==? expected) - } - } -} diff --git a/Sources/BSONReflectionTests/Main.swift b/Sources/BSONReflectionTests/Main.swift deleted file mode 100644 index 4309490e..00000000 --- a/Sources/BSONReflectionTests/Main.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Testing_ - -@main -enum Main:TestMain -{ - static - let all:[any TestBattery.Type] = [Documents.self] -} diff --git a/Sources/BSONTesting/TestGroup (ext).swift b/Sources/BSONTesting/TestGroup (ext).swift deleted file mode 100644 index a0b3c1f3..00000000 --- a/Sources/BSONTesting/TestGroup (ext).swift +++ /dev/null @@ -1,29 +0,0 @@ -import BSON -import Testing_ - -extension TestGroup -{ - @discardableResult - public - func roundtrip(_ codable:Codable, - function:String = #function, - file:String = #fileID, - line:Int = #line) -> Bool - where Codable:BSONDocumentDecodable & BSONDocumentEncodable & Equatable - { - let encoded:BSON.Document = .init(encoding: codable) - let decoded:Codable? = self.do(function: function, file: file, line: line) - { - try .init(bson: encoded) - } - if let decoded, - let self:TestGroup = self / "Comparison" - { - return self.expect(decoded ==? codable) - } - else - { - return false - } - } -} diff --git a/Sources/BSONTesting/exports.swift b/Sources/BSONTesting/exports.swift deleted file mode 100644 index 9e885de7..00000000 --- a/Sources/BSONTesting/exports.swift +++ /dev/null @@ -1 +0,0 @@ -@_exported import Testing_ diff --git a/Sources/BSONTests/Main.InvalidBSON.swift b/Sources/BSONTests/Main.InvalidBSON.swift deleted file mode 100644 index 63fc7e36..00000000 --- a/Sources/BSONTests/Main.InvalidBSON.swift +++ /dev/null @@ -1,328 +0,0 @@ -import Base16 -import BSON -import BSONReflection -import Testing_ - -extension Main -{ - enum InvalidBSON - { - } -} -extension Main.InvalidBSON:TestBattery -{ - static - func run(tests:TestGroup) - { - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/boolean.json - if let tests:TestGroup = tests / "bool" - { - Self.run(tests / "invalid-subtype", - invalid: "090000000862000200", - catching: BSON.BooleanSubtypeError.init(invalid: 2)) - - Self.run(tests / "invalid-subtype-negative", - invalid: "09000000086200FF00", - catching: BSON.BooleanSubtypeError.init(invalid: 255)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/int32.json - if let tests:TestGroup = tests / "int32" - { - Self.run(tests / "truncated", - invalid: "09000000_10_6100_05_00", - catching: BSON.InputError.init(expected: .bytes(4), encountered: 1)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/int32.json - if let tests:TestGroup = tests / "int64" - { - Self.run(tests / "truncated", - invalid: "0C000000_12_6100_12345678_00", - catching: BSON.InputError.init(expected: .bytes(8), encountered: 4)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/timestamp.json - if let tests:TestGroup = tests / "uint64" - { - Self.run(tests / "truncated", - invalid: "0F000000_11_6100_2A00000015CD5B_00", - catching: BSON.InputError.init(expected: .bytes(8), encountered: 7)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/top.json - if let tests:TestGroup = tests / "top" - { - Self.run(tests / "zeroes", - invalid: "00000000_000000000000", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: 0)) - - Self.run(tests / "invalid-length-over", - invalid: "12000000_02_666F6F00_04000000_626172", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x12 - 4), encountered: 12)) - - Self.run(tests / "invalid-length-under", - invalid: "12000000_02_666F6F00_04000000_62617200_00_DEADBEEF", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .end, encountered: 4)) - - Self.run(tests / "invalid-type-0x00", - invalid: "07000000_00_0000", - // ^~ - catching: BSON.TypeError.init(invalid: 0x00)) - - Self.run(tests / "invalid-type-0x80", - invalid: "07000000_80_0000", - // ^~ - catching: BSON.TypeError.init(invalid: 0x80)) - - Self.run(tests / "truncated", - invalid: "12000000_02_666F", - catching: BSON.InputError.init(expected: .bytes(0x12 - 4), encountered: 3)) - - Self.run(tests / "invalid-key", - invalid: "0D000000_10_7800_00_0100000000", - // ^~ - catching: BSON.TypeError.init(invalid: 0x00)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/datetime.json - if let tests:TestGroup = tests / "millisecond" - { - Self.run(tests / "truncated", - invalid: "0C000000_0961001234567800", - catching: BSON.InputError.init(expected: .bytes(8), encountered: 4)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/double.json - if let tests:TestGroup = tests / "double" - { - // note: frameshift - Self.run(tests / "truncated", - invalid: "0B000000_0164000000F03F00", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .end, encountered: 1)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/oid.json - if let tests:TestGroup = tests / "id" - { - Self.run(tests / "truncated", - invalid: "12000000_07_6100_56E1FC72E0C917E9C471", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x12 - 4), encountered: 13)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/dbpointer.json - if let tests:TestGroup = tests / "pointer" - { - Self.run(tests / "invalid-length-negative", - invalid: "1A000000_0C_6100_FFFFFFFF_620056E1FC72E0C917E9C471416100", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: -1)) - - Self.run(tests / "invalid-length-zero", - invalid: "1A000000_0C_6100_00000000_620056E1FC72E0C917E9C471416100", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: 0)) - - Self.run(tests / "truncated", - invalid: "16000000_0C_6100_03000000_616200_56E1FC72E0C91700", - catching: BSON.InputError.init(expected: .bytes(12), encountered: 7)) - - Self.run(tests / "truncated-identifier", - invalid: "1A000000_0C_6100_03000000_616200_56E1FC72E0C917E9C4716100", - catching: BSON.InputError.init(expected: .bytes(12), encountered: 11)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/binary.json - if let tests:TestGroup = tests / "binary" - { - Self.run(tests / "invalid-length-over", - invalid: "1D000000_05_7800_FF000000_05_73FFD26444B34C6990E8E7D1DFC035D400", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0xFF + 1), encountered: 17)) - - Self.run(tests / "invalid-length-negative", - invalid: "0D000000057800FFFFFFFF0000", - catching: BSON.BinaryViewError.init(expected: .subtype)) - // TODO: tests for legacy binary subtype 0x02 - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/document.json - if let tests:TestGroup = tests / "document" - { - Self.run(tests / "invalid-length-over", - invalid: "18000000_03_666F6F00_0F000000_10_62617200_FFFFFF7F_0000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x0F - 4), encountered: 10)) - - Self.run(tests / "invalid-length-under", - invalid: "15000000_03_666F6F00_0A000000_08_62617200_01_00_00", - // ^~ - catching: BSON.InputError.init(expected: .bytes(1))) - - Self.run(tests / "invalid-value", - invalid: "1C000000_03_666F6F00_12000000_02_62617200_05000000_62617A000000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(5), encountered: 4)) - - Self.run(tests / "invalid-key", - invalid: "15000000_03_7800_0D000000_10_6100_00010000_00_0000", - // ^~ - catching: BSON.TypeError.init(invalid: 0)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/array.json - if let tests:TestGroup = tests / "tuple" - { - Self.run(tests / "invalid-length-over", - invalid: "14000000_04_6100_0D000000_10_30000A00_00_000000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x0D - 4), encountered: 8)) - - Self.run(tests / "invalid-length-under", - invalid: "14000000_04_6100_0B000000_10_30000A00_00_000000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(4), encountered: 3)) - - Self.run(tests / "invalid-element", - invalid: "1A000000_04_666F6F00_100000000230000500000062617A000000", - // - catching: BSON.InputError.init(expected: .bytes(5), encountered: 4)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/regex.json - if let tests:TestGroup = tests / "regex" - { - // note: frameshift - Self.run(tests / "invalid-pattern", - invalid: "0F0000000B610061006300696D0000", - catching: BSON.Regex.OptionError.init(invalid: "c")) - // note: frameshift - Self.run(tests / "invalid-options", - invalid: "100000000B61006162630069006D0000", - catching: BSON.TypeError.init(invalid: 109)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/string.json - if let tests:TestGroup = tests / "string" - { - Self.run(tests / "missing-trailing-null-byte", - invalid: "0C000000_02_6100_00000000_00", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: 0)) - - Self.run(tests / "invalid-length-negative", - invalid: "0C000000_02_6100_FFFFFFFF_00", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: -1)) - - Self.run(tests / "invalid-length-over", - invalid: "10000000_02_6100_05000000_62006200_00", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(5), encountered: 4)) - - Self.run(tests / "invalid-length-over-document", - invalid: "12000000_02_00_FFFFFF00_666F6F6261720000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0xffffff), encountered: 7)) - - Self.run(tests / "invalid-length-under", - invalid: "0E000000_02_6100_01000000_00_00_00", - // ^~ - catching: BSON.TypeError.init(invalid: 0x00)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/code.json - if let tests:TestGroup = tests / "javascript" - { - Self.run(tests / "missing-trailing-null-byte", - invalid: "0C000000_0D_6100_00000000_00", - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: 0)) - - Self.run(tests / "invalid-length-negative", - invalid: "0C0000000D6100FFFFFFFF00", - catching: BSON.HeaderError.init(length: -1)) - - Self.run(tests / "invalid-length-over", - invalid: "10000000_0D_6100_05000000_6200620000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(5), encountered: 4)) - - Self.run(tests / "invalid-length-over-document", - invalid: "12000000_0D_00_FFFFFF00_666F6F6261720000", - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0xffffff), encountered: 7)) - - Self.run(tests / "invalid-length-under", - invalid: "0E000000_0D_6100_01000000_00_00_00", - // ^~ - catching: BSON.TypeError.init(invalid: 0x00)) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/code_w_scope.json - if let tests:TestGroup = tests / "javascript-scope" - { - // note: we do not validate the redundant field length, - // so those tests are not included - - // note: the length is actually too short, but because we use the component-wise - // length headers instead of the field length, this manifests itself as a - // frameshift error. - Self.run(tests / "invalid-length-frameshift-clips-scope", - invalid: """ - 28000000_0F_6100_20000000_04000000_61626364_00130000_0010780001000000107900010000000000 - """, - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x00_00_13_00 - 4), encountered: 16)) - - Self.run(tests / "invalid-length-over", - invalid: """ - 28000000_0F_6100_20000000_06000000_616263640013_00000010_780001000000107900010000000000 - """, - // ^~~~~~~~ - catching: BSON.InputError.init(expected: .bytes(0x10_00_00_00 - 4), encountered: 14)) - // note: frameshift - Self.run(tests / "invalid-length-frameshift", - invalid: """ - 28000000_0F_6100_20000000_FF000000_61626364001300000010780001000000107900010000000000 - """, - catching: BSON.InputError.init(expected: .bytes(255), encountered: 24)) - - Self.run(tests / "invalid-scope", - invalid: """ - 1C000000_0F_00_15000000_01000000_00_0C000000_02_00000000_00000000 - """, - // ^~~~~~~~ - catching: BSON.HeaderError.init(length: 0)) - } - } -} -extension Main.InvalidBSON -{ - private static - func run(_ tests:TestGroup?, invalid:String, catching error:some Error & Equatable) - { - guard - let tests:TestGroup - else - { - return - } - - let invalid:[UInt8] = Base16.decode(invalid.utf8) - - var input:BSON.Input = .init(invalid[...]) - - tests.do(catching: error) - { - let document:BSON.Document = try input.parse(as: BSON.Document.self) - try input.finish() - _ = try document.canonicalized() - } - } -} diff --git a/Sources/BSONTests/Main.ValidBSON.swift b/Sources/BSONTests/Main.ValidBSON.swift deleted file mode 100644 index 64e560d7..00000000 --- a/Sources/BSONTests/Main.ValidBSON.swift +++ /dev/null @@ -1,635 +0,0 @@ -import Base16 -import BSON -import BSONReflection -import BSON_UUID -import UnixTime -import UUID -import Testing_ - -extension Main -{ - enum ValidBSON - { - } -} -extension Main.ValidBSON:TestBattery -{ - static - func run(tests:TestGroup) - { - enum TestKey:String - { - case a - case b - case x - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/multi-type.json - // cannot use this test, because it encodes a deprecated binary subtype, which is - // (intentionally) impossible to construct with swift-bson. - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/maxkey.json - do - { - Self.run(tests / "max", - canonical: "080000007F610000", - expected: ["a": .max]) - } - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/minkey.json - do - { - Self.run(tests / "min", - canonical: "08000000FF610000", - expected: ["a": .min]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/null.json - do - { - Self.run(tests / "null", - canonical: "080000000A610000", - expected: ["a": .null]) - } - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/undefined.json - do - { - Self.run(tests / "undefined", - degenerate: "0800000006610000", - canonical: "080000000A610000", - expected: ["a": .null]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/boolean.json - if let tests:TestGroup = tests / "bool" - { - Self.run(tests / "true", - canonical: "090000000862000100", - expected: ["b": true]) - Self.run(tests / "false", - canonical: "090000000862000000", - expected: ["b": false]) - - Self.run(tests / "true2", - canonical: "090000000862000100", - expected: .init(TestKey.self) { $0[.b] = true }) - Self.run(tests / "false2", - canonical: "090000000862000000", - expected: .init(TestKey.self) { $0[.b] = false }) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/int32.json - if let tests:TestGroup = tests / "int32" - { - Self.run(tests / "min", - canonical: "0C0000001069000000008000", - expected: ["i": .int32(-2147483648)]) - - Self.run(tests / "max", - canonical: "0C000000106900FFFFFF7F00", - expected: ["i": .int32(2147483647)]) - - Self.run(tests / "-1", - canonical: "0C000000106900FFFFFFFF00", - expected: ["i": .int32(-1)]) - - Self.run(tests / "0", - canonical: "0C0000001069000000000000", - expected: ["i": .int32(0)]) - - Self.run(tests / "+1", - canonical: "0C0000001069000100000000", - expected: ["i": .int32(1)]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/int32.json - if let tests:TestGroup = tests / "int64" - { - Self.run(tests / "min", - canonical: "10000000126100000000000000008000", - expected: ["a": .int64(-9223372036854775808)]) - - Self.run(tests / "max", - canonical: "10000000126100FFFFFFFFFFFFFF7F00", - expected: ["a": .int64(9223372036854775807)]) - - Self.run(tests / "-1", - canonical: "10000000126100FFFFFFFFFFFFFFFF00", - expected: ["a": .int64(-1)]) - - Self.run(tests / "0", - canonical: "10000000126100000000000000000000", - expected: ["a": .int64(0)]) - - Self.run(tests / "+1", - canonical: "10000000126100010000000000000000", - expected: ["a": .int64(1)]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/timestamp.json - if let tests:TestGroup = tests / "uint64" - { - Self.run(tests / "(123456789, 42)", - canonical: "100000001161002A00000015CD5B0700", - expected: ["a": .timestamp(.init(123456789 << 32 | 42))]) - - Self.run(tests / "ones", - canonical: "10000000116100FFFFFFFFFFFFFFFF00", - expected: ["a": .timestamp(.max)]) - - Self.run(tests / "(4000000000, 4000000000)", - canonical: "1000000011610000286BEE00286BEE00", - expected: ["a": .timestamp(.init(4000000000 << 32 | 4000000000))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/top.json - if let tests:TestGroup = tests / "top" - { - Self.run(tests / "dollar-prefixed-key", - canonical: "0F00000010246B6579002A00000000", - expected: ["$key": .int32(42)]) - - Self.run(tests / "dollar-key", - canonical: "0E00000002240002000000610000", - expected: ["$": "a"]) - - Self.run(tests / "dotted-key", - canonical: "1000000002612E620002000000630000", - expected: ["a.b": "c"]) - - Self.run(tests / "dot-key", - canonical: "0E000000022E0002000000610000", - expected: [".": "a"]) - - Self.run(tests / "empty-truncated-header", - degenerate: "0100000000", - canonical: "0500000000", - expected: [:]) - - Self.run(tests / "empty", - canonical: "0500000000", - expected: [:]) - - Self.run(tests / "invalid-end-of-object-0x01", - degenerate: "05000000_01", - canonical: "05000000_00", - expected: [:]) - - Self.run(tests / "invalid-end-of-object-0xff", - degenerate: "05000000_FF", - canonical: "05000000_00", - expected: [:]) - - Self.run(tests / "invalid-end-of-object-0x70", - degenerate: "05000000_70", - canonical: "05000000_00", - expected: [:]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/decimal128-1.json - if let tests:TestGroup = tests / "decimal128" - { - Self.run(tests / "positive-quiet-nan", - canonical: "180000001364000000000000000000000000000000007C00", - expected: ["d": .decimal128(.init( - high: 0x7C00_0000_0000_0000, - low: 0x0000_0000_0000_0000))]) - - Self.run(tests / "negative-quiet-nan", - canonical: "18000000136400000000000000000000000000000000FC00", - expected: ["d": .decimal128(.init( - high: 0xFC00_0000_0000_0000, - low: 0x0000_0000_0000_0000))]) - - Self.run(tests / "positive-signaling-nan", - canonical: "180000001364000000000000000000000000000000007E00", - expected: ["d": .decimal128(.init( - high: 0x7E00_0000_0000_0000, - low: 0x0000_0000_0000_0000))]) - - Self.run(tests / "negative-signaling-nan", - canonical: "18000000136400000000000000000000000000000000FE00", - expected: ["d": .decimal128(.init( - high: 0xFE00_0000_0000_0000, - low: 0x0000_0000_0000_0000))]) - - // this only serves to verify we are handling byte-order correctly; - // there is very little point in elaborating decimal128 tests further - Self.run(tests / "largest", - canonical: "18000000136400F2AF967ED05C82DE3297FF6FDE3C403000", - expected: ["d": .decimal128(.init( - high: 0x3040_3CDE_6FFF_9732, - low: 0xDE82_5CD0_7E96_AFF2))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/datetime.json - if let tests:TestGroup = tests / "millisecond" - { - Self.run(tests / "epoch", - canonical: "10000000096100000000000000000000", - expected: ["a": .millisecond(.init(index: 0))]) - - Self.run(tests / "positive", - canonical: "10000000096100C5D8D6CC3B01000000", - expected: ["a": .millisecond(.init(index: 1356351330501))]) - - Self.run(tests / "negative", - canonical: "10000000096100C33CE7B9BDFFFFFF00", - expected: ["a": .millisecond(.init(index: -284643869501))]) - - Self.run(tests / "positive-2", - canonical: "1000000009610000DC1FD277E6000000", - expected: ["a": .millisecond(.init(index: 253402300800000))]) - - Self.run(tests / "positive-3", - canonical: "10000000096100D1D6D6CC3B01000000", - expected: ["a": .millisecond(.init(index: 1356351330001))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/double.json - if let tests:TestGroup = tests / "double" - { - Self.run(tests / "+1.0", - canonical: "10000000016400000000000000F03F00", - expected: ["d": .double(1.0)]) - - Self.run(tests / "-1.0", - canonical: "10000000016400000000000000F0BF00", - expected: ["d": .double(-1.0)]) - - Self.run(tests / "+1.0001220703125", - canonical: "10000000016400000000008000F03F00", - expected: ["d": .double(1.0001220703125)]) - - Self.run(tests / "-1.0001220703125", - canonical: "10000000016400000000008000F0BF00", - expected: ["d": .double(-1.0001220703125)]) - - Self.run(tests / "1.2345678921232E+18", - canonical: "100000000164002a1bf5f41022b14300", - expected: ["d": .double(1.2345678921232e18)]) - - Self.run(tests / "-1.2345678921232E+18", - canonical: "100000000164002a1bf5f41022b1c300", - expected: ["d": .double(-1.2345678921232e18)]) - - // remaining corpus test cases are pointless because swift cannot distinguish - // between -0.0 and +0.0 - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/oid.json - if let tests:TestGroup = tests / "id" - { - let id:BSON.Identifier = 0x0123_4567_89AB_CDEF_4567_3210 - - tests.expect(id.timestamp ==? 0x0123_4567) - tests.expect(true: id.seed == (0x89, 0xAB, 0xCD, 0xEF, 0x45)) - tests.expect(true: id.ordinal == (0x67, 0x32, 0x10)) - - tests.expect(id ==? .init(timestamp: id.timestamp, seed: id.seed, ordinal: id.ordinal)) - - Self.run(tests / "zeroes", - canonical: "1400000007610000000000000000000000000000", - expected: ["a": .id(0x00000000_00000000_00_000000)]) - - Self.run(tests / "ones", - canonical: "14000000076100FFFFFFFFFFFFFFFFFFFFFFFF00", - expected: ["a": .id(0xffffffff_ffffffff_ff_ffffff)]) - - Self.run(tests / "random", - canonical: "1400000007610056E1FC72E0C917E9C471416100", - expected: ["a": .id(0x56e1fc72_e0c917e9_c4_714161)]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/dbpointer.json - if let tests:TestGroup = tests / "pointer" - { - - Self.run(tests / "ascii", - canonical: "1A0000000C610002000000620056E1FC72E0C917E9C471416100", - expected: ["a": .pointer(.init(from: "b"), .init( - 0x56e1fc72, 0xe0c917e9, 0xc4_714161))]) - - Self.run(tests / "unicode", - canonical: "1B0000000C610003000000C3A90056E1FC72E0C917E9C471416100", - expected: ["a": .pointer(.init(from: "é"), .init( - 0x56e1fc72, 0xe0c917e9, 0xc4_714161))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/binary.json - if let tests:TestGroup = tests / "binary" - { - Self.run(tests / "generic-empty", - canonical: "0D000000057800000000000000", - expected: ["x": .binary(.init(subtype: .generic, bytes: []))]) - - Self.run(tests / "generic", - canonical: "0F0000000578000200000000FFFF00", - expected: ["x": .binary(.init(subtype: .generic, - bytes: Base16.decode("ffff")))]) - - Self.run(tests / "function", - canonical: "0F0000000578000200000001FFFF00", - expected: ["x": .binary(.init(subtype: .function, - bytes: Base16.decode("ffff")))]) - - Self.run(tests / "function2", - canonical: "0F0000000578000200000001FFFF00", - expected: ["x": .binary(.init { $0.subtype = .function ; $0 += [0xff, 0xff] })]) - - Self.run(tests / "uuid", - canonical: "1D000000057800100000000473FFD26444B34C6990E8E7D1DFC035D400", - expected: ["x": .binary(.init(subtype: .uuid, - bytes: Base16.decode("73ffd26444b34c6990e8e7d1dfc035d4")))]) - Self.run(tests / "uuid2", - canonical: "1D000000057800100000000473FFD26444B34C6990E8E7D1DFC035D400", - expected: .init(TestKey.self) - { - $0[.x] = UUID.init(0x73ffd26444b34c69, 0x90e8e7d1dfc035d4) - }) - - Self.run(tests / "md5", - canonical: "1D000000057800100000000573FFD26444B34C6990E8E7D1DFC035D400", - expected: ["x": .binary(.init(subtype: .md5, - bytes: Base16.decode("73ffd26444b34c6990e8e7d1dfc035d4")))]) - - Self.run(tests / "compressed", - canonical: "1D000000057800100000000773FFD26444B34C6990E8E7D1DFC035D400", - expected: ["x": .binary(.init(subtype: .compressed, - bytes: Base16.decode("73ffd26444b34c6990e8e7d1dfc035d4")))]) - - Self.run(tests / "custom", - canonical: "0F0000000578000200000080FFFF00", - expected: ["x": .binary(.init(subtype: .custom(code: 0x80), - bytes: Base16.decode("ffff")))]) - // TODO: tests for legacy binary subtype 0x02 - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/document.json - if let tests:TestGroup = tests / "document" - { - Self.run(tests / "empty", - canonical: "0D000000037800050000000000", - expected: ["x": [:]]) - - Self.run(tests / "empty-key", - canonical: "150000000378000D00000002000200000062000000", - expected: ["x": ["": "b"]]) - - Self.run(tests / "single-character-key", - canonical: "160000000378000E0000000261000200000062000000", - expected: ["x": ["a": "b"]]) - - Self.run(tests / "dollar-prefixed-key", - canonical: "170000000378000F000000022461000200000062000000", - expected: ["x": ["$a": "b"]]) - - Self.run(tests / "dollar-key", - canonical: "160000000378000E0000000224000200000061000000", - expected: ["x": ["$": "a"]]) - - Self.run(tests / "dotted-key", - canonical: "180000000378001000000002612E62000200000063000000", - expected: ["x": ["a.b": "c"]]) - - Self.run(tests / "dot-key", - canonical: "160000000378000E000000022E000200000061000000", - expected: ["x": [".": "a"]]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/array.json - if let tests:TestGroup = tests / "tuple" - { - Self.run(tests / "empty", - canonical: "0D000000046100050000000000", - expected: ["a": []]) - Self.run(tests / "single-element", - canonical: "140000000461000C0000001030000A0000000000", - expected: ["a": [.int32(10)]]) - - Self.run(tests / "single-element-empty-key", - degenerate: "130000000461000B00000010000A0000000000", - canonical: "140000000461000C0000001030000A0000000000", - expected: ["a": [.int32(10)]]) - - Self.run(tests / "single-element-invalid-key", - degenerate: "150000000461000D000000106162000A0000000000", - canonical: "140000000461000C0000001030000A0000000000", - expected: ["a": [.int32(10)]]) - - Self.run(tests / "multiple-element-duplicate-keys", - degenerate: "1b000000046100130000001030000a000000103000140000000000", - canonical: "1b000000046100130000001030000a000000103100140000000000", - expected: ["a": [.int32(10), .int32(20)]]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/regex.json - if let tests:TestGroup = tests / "regex" - { - Self.run(tests / "empty", - canonical: "0A0000000B6100000000", - expected: ["a": .regex(.init(pattern: "", options: []))]) - - Self.run(tests / "empty-options", - canonical: "0D0000000B6100616263000000", - expected: ["a": .regex(.init(pattern: "abc", options: []))]) - - Self.run(tests / "I-HAVE-OPTIONS", - canonical: "0F0000000B610061626300696D0000", - expected: ["a": .regex(.init(pattern: "abc", options: [.i, .m]))]) - - Self.run(tests / "slash", - canonical: "110000000B610061622F636400696D0000", - expected: ["a": .regex(.init(pattern: "ab/cd", options: [.i, .m]))]) - - Self.run(tests / "non-alphabetized", - degenerate: "100000000B6100616263006D69780000", - canonical: "100000000B610061626300696D780000", - expected: ["a": .regex(.init(pattern: "abc", options: [.i, .m, .x]))]) - - Self.run(tests / "escaped", - canonical: "100000000B610061625C226162000000", - expected: ["a": .regex(.init(pattern: #"ab\"ab"#, options: []))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/string.json - if let tests:TestGroup = tests / "string" - { - Self.run(tests / "empty", - canonical: "0D000000026100010000000000", - expected: ["a": ""]) - - Self.run(tests / "single-character", - canonical: "0E00000002610002000000620000", - expected: ["a": "b"]) - - Self.run(tests / "multiple-character", - canonical: "190000000261000D0000006162616261626162616261620000", - expected: ["a": "abababababab"]) - - Self.run(tests / "utf-8-double-code-unit", - canonical: "190000000261000D000000C3A9C3A9C3A9C3A9C3A9C3A90000", - expected: ["a": "\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}"]) - - Self.run(tests / "utf-8-triple-code-unit", - canonical: "190000000261000D000000E29886E29886E29886E298860000", - expected: ["a": "\u{2606}\u{2606}\u{2606}\u{2606}"]) - - Self.run(tests / "utf-8-null-bytes", - canonical: "190000000261000D0000006162006261620062616261620000", - expected: ["a": "ab\u{00}bab\u{00}babab"]) - - Self.run(tests / "escaped", - canonical: - """ - 3200000002610026000000\ - 61625C220102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F6162\ - 0000 - """, - expected: - [ - "a": - """ - ab\\\"\u{01}\u{02}\u{03}\u{04}\u{05}\u{06}\u{07}\u{08}\ - \t\n\u{0b}\u{0c}\r\u{0e}\u{0f}\u{10}\ - \u{11}\u{12}\u{13}\u{14}\u{15}\u{16}\u{17}\u{18}\u{19}\ - \u{1a}\u{1b}\u{1c}\u{1d}\u{1e}\u{1f}ab - """ - ]) - - Self.run(tests / "invalid-utf-8", - canonical: "0E00000002610002000000E90000", - expected: ["a": .string(.init(bytes: [0xe9]))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/symbol.json - if let tests:TestGroup = tests / "symbol" - { - Self.run(tests / "empty", - degenerate: "0D0000000E6100010000000000", - canonical: "0D000000026100010000000000", - expected: ["a": ""]) - - Self.run(tests / "single-character", - degenerate: "0E0000000E610002000000620000", - canonical: "0E00000002610002000000620000", - expected: ["a": "b"]) - - Self.run(tests / "multiple-character", - degenerate: "190000000E61000D0000006162616261626162616261620000", - canonical: "190000000261000D0000006162616261626162616261620000", - expected: ["a": "abababababab"]) - - Self.run(tests / "utf-8-double-code-unit", - degenerate: "190000000E61000D000000C3A9C3A9C3A9C3A9C3A9C3A90000", - canonical: "190000000261000D000000C3A9C3A9C3A9C3A9C3A9C3A90000", - expected: ["a": "\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}"]) - - Self.run(tests / "utf-8-triple-code-unit", - degenerate: "190000000E61000D000000E29886E29886E29886E298860000", - canonical: "190000000261000D000000E29886E29886E29886E298860000", - expected: ["a": "\u{2606}\u{2606}\u{2606}\u{2606}"]) - - Self.run(tests / "utf-8-null-bytes", - degenerate: "190000000E61000D0000006162006261620062616261620000", - canonical: "190000000261000D0000006162006261620062616261620000", - expected: ["a": "ab\u{00}bab\u{00}babab"]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/code.json - if let tests:TestGroup = tests / "javascript" - { - Self.run(tests / "empty", - canonical: "0D0000000D6100010000000000", - expected: ["a": .javascript(.init(from: ""))]) - - Self.run(tests / "single-character", - canonical: "0E0000000D610002000000620000", - expected: ["a": .javascript(.init(from: "b"))]) - - Self.run(tests / "multiple-character", - canonical: "190000000D61000D0000006162616261626162616261620000", - expected: ["a": .javascript(.init(from: "abababababab"))]) - - Self.run(tests / "utf-8-double-code-unit", - canonical: "190000000D61000D000000C3A9C3A9C3A9C3A9C3A9C3A90000", - expected: ["a": .javascript(.init(from: "\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}\u{e9}"))]) - - Self.run(tests / "utf-8-triple-code-unit", - canonical: "190000000D61000D000000E29886E29886E29886E298860000", - expected: ["a": .javascript(.init(from: "\u{2606}\u{2606}\u{2606}\u{2606}"))]) - - Self.run(tests / "utf-8-null-bytes", - canonical: "190000000D61000D0000006162006261620062616261620000", - expected: ["a": .javascript(.init(from: "ab\u{00}bab\u{00}babab"))]) - } - - // https://github.com/mongodb/specifications/blob/master/source/bson-corpus/tests/code_w_scope.json - if let tests:TestGroup = tests / "javascript-scope" - { - Self.run(tests / "empty", - canonical: "160000000F61000E0000000100000000050000000000", - expected: ["a": .javascriptScope([:], .init(from: ""))]) - - Self.run(tests / "empty-scope", - canonical: "1A0000000F610012000000050000006162636400050000000000", - expected: ["a": .javascriptScope([:], .init(from: "abcd"))]) - - Self.run(tests / "empty-code", - canonical: "1D0000000F61001500000001000000000C000000107800010000000000", - expected: ["a": .javascriptScope(["x": .int32(1)], .init(from: ""))]) - - Self.run(tests / "non-empty", - canonical: "210000000F6100190000000500000061626364000C000000107800010000000000", - expected: ["a": .javascriptScope(["x": .int32(1)], .init(from: "abcd"))]) - - Self.run(tests / "unicode", - canonical: "1A0000000F61001200000005000000C3A9006400050000000000", - expected: ["a": .javascriptScope([:], .init(from: "\u{e9}\u{00}d"))]) - } - } -} -extension Main.ValidBSON -{ - private static - func run(_ tests:TestGroup?, - degenerate:String? = nil, - canonical:String, - expected:BSON.Document) - { - guard let tests:TestGroup - else - { - return - } - - let canonical:[UInt8] = Base16.decode(canonical.utf8) - let size:Int32 = canonical.prefix(4).withUnsafeBytes - { - .init(littleEndian: $0.load(as: Int32.self)) - } - - let document:BSON.Document = .init( - slicing: canonical.dropFirst(4).dropLast()) - - tests.expect(canonical.count ==? .init(size)) - tests.expect(document.header ==? size) - - tests.expect(true: expected ~~ document) - tests.expect(expected ==? document) - - if let degenerate:String - { - let degenerate:[UInt8] = Base16.decode(degenerate.utf8) - let document:BSON.Document = .init( - slicing: degenerate.dropFirst(4).dropLast()) - - (tests / "canonicalization")?.do - { - let canonicalized:BSON.Document = try document.canonicalized() - - tests.expect(true: expected ~~ document) - tests.expect(true: expected == canonicalized) - } - } - } -} diff --git a/Sources/BSONTests/Main.swift b/Sources/BSONTests/Main.swift deleted file mode 100644 index dbb9ec41..00000000 --- a/Sources/BSONTests/Main.swift +++ /dev/null @@ -1,8 +0,0 @@ -import Testing_ - -@main -enum Main:TestMain -{ - static - let all:[any TestBattery.Type] = [ValidBSON.self, InvalidBSON.self] -} diff --git a/Sources/BSON_OrderedCollections/OrderedDictionary (ext).swift b/Sources/BSON_OrderedCollections/OrderedDictionary (ext).swift deleted file mode 100644 index a00a0e10..00000000 --- a/Sources/BSON_OrderedCollections/OrderedDictionary (ext).swift +++ /dev/null @@ -1,38 +0,0 @@ -import BSON -import OrderedCollections - -extension OrderedDictionary:BSONDecodable where Key == BSON.Key, Value:BSONDecodable -{ - @inlinable public - init(bson:BSON.AnyValue) throws - { - try self.init(bson: try .init(bson: consume bson)) - } - @inlinable public - init(bson:BSON.Document) throws - { - self.init() - try bson.parse - { - (field:BSON.FieldDecoder) in - - if case _? = self.updateValue(try field.decode(to: Value.self), - forKey: field.key) - { - throw BSON.DocumentKeyError.duplicate(field.key) - } - } - } -} -extension OrderedDictionary:BSONDocumentEncodable, BSONEncodable - where Key == BSON.Key, Value:BSONEncodable -{ - @inlinable public - func encode(to bson:inout BSON.DocumentEncoder) - { - for (key, value):(Key, Value) in self.elements - { - bson[key] = value - } - } -} diff --git a/Sources/BSON_UUID/UUID (ext).swift b/Sources/BSON_UUID/UUID (ext).swift deleted file mode 100644 index 6e4b85cd..00000000 --- a/Sources/BSON_UUID/UUID (ext).swift +++ /dev/null @@ -1,24 +0,0 @@ -import BSON -import UUID - -extension UUID:BSONBinaryDecodable -{ - @inlinable public - init(bson:BSON.BinaryDecoder) throws - { - try bson.subtype.expect(.uuid) - try bson.shape.expect(length: 16) - - self.init(bson.bytes) - } -} -extension UUID:BSONBinaryEncodable -{ - @inlinable public - func encode(to bson:inout BSON.BinaryEncoder) - { - bson.subtype = .uuid - bson.reserve(another: 16) - bson += self - } -} diff --git a/Sources/UUID/UUID.swift b/Sources/UUID/UUID.swift deleted file mode 100644 index 66d9af51..00000000 --- a/Sources/UUID/UUID.swift +++ /dev/null @@ -1,140 +0,0 @@ -import Base16 - -@frozen public -struct UUID:Sendable -{ - /// The raw bit pattern of this UUID. - /// - /// UUIDs are always big-endian, regardless of platform endianness, so the first - /// tuple element contains the high 64 bits of the UUID, and the second tuple - /// element contains the low 64 bits. - /// - /// The constituent ``UInt64`` components are also big-endian, and so their - /// numeric value, as interpreted by the current host, may vary among host - /// machines. In particular, do *not* assume that the *n*-th bit in the *i*th - /// component corresponds to a fixed bit in the UUID. - public - let bitPattern:(UInt64, UInt64) - - /// Creates a UUID with the given bit pattern. Do not use this initializer - /// to create a UUID from integer literals; use ``init(_:_:)``, which accounts - /// for platform endianness, instead. - @inlinable public - init(bitPattern:(UInt64, UInt64)) - { - self.bitPattern = bitPattern - } - - /// Creates a UUID with the given high- and low-components. The components - /// are interpreted by platform endianness; therefore the values stored - /// into ``bitPattern`` may be different if the current host is not big-endian. - @inlinable public - init(_ high:UInt64, _ low:UInt64) - { - self.init(bitPattern: (high.bigEndian, low.bigEndian)) - } -} -extension UUID -{ - /// Generates an [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122)-compliant - /// random UUID (version 4). - @inlinable public static - func random() -> Self - { - var bitPattern:(UInt64, UInt64) = - ( - .random(in: .min ... .max), - .random(in: .min ... .max) - ) - withUnsafeMutableBytes(of: &bitPattern) - { - $0[6] = 0b0100_0000 | - 0b0000_1111 & $0[6] - $0[8] = 0b1000_0000 | - 0b0011_1111 & $0[8] - } - return .init(bitPattern: bitPattern) - } - /// Creates a UUID by initializing its raw memory from a collection of bytes. - /// If the collection does not contain at least 16 bytes, the uninitalized - /// portion of the UUID is filled with zero bytes. - @inlinable public - init(_ bytes:Bytes) where Bytes:Collection, Bytes.Element == UInt8 - { - self.init(bitPattern: (0, 0)) - withUnsafeMutableBytes(of: &self) - { - assert($0.count == 16) - $0.copyBytes(from: bytes) - } - } -} -extension UUID:Equatable -{ - @inlinable public static - func == (lhs:Self, rhs:Self) -> Bool - { - lhs.bitPattern == rhs.bitPattern - } -} -extension UUID:Hashable -{ - @inlinable public - func hash(into hasher:inout Hasher) - { - // do not use the ``UInt64`` components directly, their numeric - // values may differ by endianness - for byte:UInt8 in self - { - byte.hash(into: &hasher) - } - } -} -extension UUID:RandomAccessCollection -{ - @inlinable public - var startIndex:Int - { - 0 - } - @inlinable public - var endIndex:Int - { - 16 - } - @inlinable public - subscript(index:Int) -> UInt8 - { - precondition(self.indices ~= index) - return withUnsafeBytes(of: self) { $0[index] } - } -} -extension UUID:LosslessStringConvertible -{ - @inlinable public - init?(_ string:String) - { - // do this instead of decoding directly into raw memory so we can check - // that the byte count is exactly 16 - let bytes:[UInt8] = Base16.decode(string) - if bytes.count == 16 - { - self.init(bytes) - } - else - { - return nil - } - } - public - var description:String - { - """ - \(Base16.encode(self[ 0 ..< 4], with: Base16.LowercaseDigits.self))-\ - \(Base16.encode(self[ 4 ..< 6], with: Base16.LowercaseDigits.self))-\ - \(Base16.encode(self[ 6 ..< 8], with: Base16.LowercaseDigits.self))-\ - \(Base16.encode(self[ 8 ..< 10], with: Base16.LowercaseDigits.self))-\ - \(Base16.encode(self[10 ..< 16], with: Base16.LowercaseDigits.self)) - """ - } -}