From 885299f972c7528101576b2ab52eb680e6a034c2 Mon Sep 17 00:00:00 2001 From: Rick Newton-Rogers Date: Tue, 29 Oct 2024 09:25:19 +0000 Subject: [PATCH 1/2] Migrate to GitHub Actions Migrate CI to use GitHub Actions. Motivation: To migrate to GitHub actions and centralised infrastructure. Modifications: Changes of note: * Adopt swift-format using rules from SwiftNIO * Remove scripts and docker files which are no longer needed Result: Feature parity with old CI. --- .github/workflows/main.yml | 18 ++ .github/workflows/pull_request.yml | 30 ++++ .github/workflows/pull_request_label.yml | 18 ++ .licenseignore | 35 ++++ .swift-format | 68 ++++++++ .swiftformat | 13 -- Package.swift | 3 - Sources/RawStructuredFieldValues/ASCII.swift | 6 +- .../ComponentTypes.swift | 10 +- .../FieldParser.swift | 25 +-- .../FieldSerializer.swift | 10 +- .../PseudoDecimal.swift | 10 +- .../Decoder/BareInnerListDecoder.swift | 3 +- .../Decoder/BareItemDecoder.swift | 8 +- .../Decoder/DictionaryKeyedContainer.swift | 5 +- .../Decoder/KeyedInnerListDecoder.swift | 5 +- .../Decoder/KeyedItemDecoder.swift | 5 +- .../Decoder/KeyedTopLevelListDecoder.swift | 5 +- .../Decoder/ParametersDecoder.swift | 5 +- .../Decoder/StructuredFieldValueDecoder.swift | 25 ++- .../Decoder/TopLevelListDecoder.swift | 3 +- ...tructuredFieldKeyedEncodingContainer.swift | 7 +- ...ucturedFieldUnkeyedEncodingContainer.swift | 5 +- .../Encoder/StructuredFieldValueEncoder.swift | 36 ++-- Sources/sh-parser/main.swift | 7 +- Tests/StructuredFieldValuesTests/Base32.swift | 4 +- .../StructuredFieldValuesTests/Fixtures.swift | 24 ++- .../StructuredFieldDecoderTests.swift | 123 +++++++++++--- .../StructuredFieldEncoderTests.swift | 159 +++++++++++++----- .../StructuredFieldParserTests.swift | 74 ++++++-- .../StructuredFieldSerializerTests.swift | 31 +++- docker/Dockerfile | 33 ---- docker/docker-compose.2204.510.yaml | 25 --- docker/docker-compose.2204.58.yaml | 25 --- docker/docker-compose.2204.59.yaml | 25 --- docker/docker-compose.2204.main.yaml | 25 --- docker/docker-compose.yaml | 46 ----- scripts/check-docs.sh | 23 --- scripts/check_no_api_breakages.sh | 122 -------------- scripts/generate_docs.sh | 109 ------------ scripts/soundness.sh | 143 ---------------- 41 files changed, 599 insertions(+), 757 deletions(-) create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/pull_request.yml create mode 100644 .github/workflows/pull_request_label.yml create mode 100644 .licenseignore create mode 100644 .swift-format delete mode 100644 .swiftformat delete mode 100644 docker/Dockerfile delete mode 100644 docker/docker-compose.2204.510.yaml delete mode 100644 docker/docker-compose.2204.58.yaml delete mode 100644 docker/docker-compose.2204.59.yaml delete mode 100644 docker/docker-compose.2204.main.yaml delete mode 100644 docker/docker-compose.yaml delete mode 100755 scripts/check-docs.sh delete mode 100755 scripts/check_no_api_breakages.sh delete mode 100755 scripts/generate_docs.sh delete mode 100755 scripts/soundness.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..bda0802 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,18 @@ +name: Main + +on: + push: + branches: [main] + schedule: + - cron: "0 8,20 * * *" + +jobs: + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml new file mode 100644 index 0000000..1335ed2 --- /dev/null +++ b/.github/workflows/pull_request.yml @@ -0,0 +1,30 @@ +name: PR + +on: + pull_request: + types: [opened, reopened, synchronize] + +jobs: + soundness: + name: Soundness + uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main + with: + license_header_check_project_name: "SwiftNIO" + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error" + linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable" + + cxx-interop: + name: Cxx interop + uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main + + swift-6-language-mode: + name: Swift 6 Language Mode + uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main + if: false # Disabled for now. diff --git a/.github/workflows/pull_request_label.yml b/.github/workflows/pull_request_label.yml new file mode 100644 index 0000000..86f199f --- /dev/null +++ b/.github/workflows/pull_request_label.yml @@ -0,0 +1,18 @@ +name: PR label + +on: + pull_request: + types: [labeled, unlabeled, opened, reopened, synchronize] + +jobs: + semver-label-check: + name: Semantic Version label check + runs-on: ubuntu-latest + timeout-minutes: 1 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Check for Semantic Version label + uses: apple/swift-nio/.github/actions/pull_request_semver_label_checker@main diff --git a/.licenseignore b/.licenseignore new file mode 100644 index 0000000..3fab865 --- /dev/null +++ b/.licenseignore @@ -0,0 +1,35 @@ +.gitignore +**/.gitignore +.licenseignore +.gitattributes +.git-blame-ignore-revs +.mailfilter +.mailmap +.spi.yml +.swift-format +.editorconfig +.github/* +*.md +*.txt +*.yml +*.yaml +*.json +Package.swift +**/Package.swift +Package@-*.swift +**/Package@-*.swift +Package.resolved +**/Package.resolved +Makefile +*.modulemap +**/*.modulemap +**/*.docc/* +*.xcprivacy +**/*.xcprivacy +*.symlink +**/*.symlink +Dockerfile +**/Dockerfile +Snippets/* +dev/git.commit.template +.unacceptablelanguageignore diff --git a/.swift-format b/.swift-format new file mode 100644 index 0000000..7e8ae73 --- /dev/null +++ b/.swift-format @@ -0,0 +1,68 @@ +{ + "version" : 1, + "indentation" : { + "spaces" : 4 + }, + "tabWidth" : 4, + "fileScopedDeclarationPrivacy" : { + "accessLevel" : "private" + }, + "spacesAroundRangeFormationOperators" : false, + "indentConditionalCompilationBlocks" : false, + "indentSwitchCaseLabels" : false, + "lineBreakAroundMultilineExpressionChainComponents" : false, + "lineBreakBeforeControlFlowKeywords" : false, + "lineBreakBeforeEachArgument" : true, + "lineBreakBeforeEachGenericRequirement" : true, + "lineLength" : 120, + "maximumBlankLines" : 1, + "respectsExistingLineBreaks" : true, + "prioritizeKeepingFunctionOutputTogether" : true, + "noAssignmentInExpressions" : { + "allowedFunctions" : [ + "XCTAssertNoThrow", + "XCTAssertThrowsError" + ] + }, + "rules" : { + "AllPublicDeclarationsHaveDocumentation" : false, + "AlwaysUseLiteralForEmptyCollectionInit" : false, + "AlwaysUseLowerCamelCase" : false, + "AmbiguousTrailingClosureOverload" : true, + "BeginDocumentationCommentWithOneLineSummary" : false, + "DoNotUseSemicolons" : true, + "DontRepeatTypeInStaticProperties" : true, + "FileScopedDeclarationPrivacy" : true, + "FullyIndirectEnum" : true, + "GroupNumericLiterals" : true, + "IdentifiersMustBeASCII" : true, + "NeverForceUnwrap" : false, + "NeverUseForceTry" : false, + "NeverUseImplicitlyUnwrappedOptionals" : false, + "NoAccessLevelOnExtensionDeclaration" : true, + "NoAssignmentInExpressions" : true, + "NoBlockComments" : true, + "NoCasesWithOnlyFallthrough" : true, + "NoEmptyTrailingClosureParentheses" : true, + "NoLabelsInCasePatterns" : true, + "NoLeadingUnderscores" : false, + "NoParensAroundConditions" : true, + "NoVoidReturnOnFunctionSignature" : true, + "OmitExplicitReturns" : true, + "OneCasePerLine" : true, + "OneVariableDeclarationPerLine" : true, + "OnlyOneTrailingClosureArgument" : true, + "OrderedImports" : true, + "ReplaceForEachWithForLoop" : true, + "ReturnVoidInsteadOfEmptyTuple" : true, + "UseEarlyExits" : false, + "UseExplicitNilCheckInConditions" : false, + "UseLetInEveryBoundCaseVariable" : false, + "UseShorthandTypeNames" : true, + "UseSingleLinePropertyGetter" : false, + "UseSynthesizedInitializer" : false, + "UseTripleSlashForDocumentationComments" : true, + "UseWhereClausesInForLoops" : false, + "ValidateDocumentationComments" : false + } +} diff --git a/.swiftformat b/.swiftformat deleted file mode 100644 index 1a2dcb1..0000000 --- a/.swiftformat +++ /dev/null @@ -1,13 +0,0 @@ -# file options - ---swiftversion 5.4 ---exclude .build - -# format options - ---self insert ---patternlet inline ---stripunusedargs unnamed-only ---ifdef no-indent - -# rules diff --git a/Package.swift b/Package.swift index b0df52c..dacc987 100644 --- a/Package.swift +++ b/Package.swift @@ -26,9 +26,6 @@ let package = Package( targets: ["RawStructuredFieldValues"] ), ], - dependencies: [ - .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), - ], targets: [ .target( name: "RawStructuredFieldValues", diff --git a/Sources/RawStructuredFieldValues/ASCII.swift b/Sources/RawStructuredFieldValues/ASCII.swift index 44c5991..6a56010 100644 --- a/Sources/RawStructuredFieldValues/ASCII.swift +++ b/Sources/RawStructuredFieldValues/ASCII.swift @@ -21,7 +21,7 @@ let asciiUnderscore = UInt8(ascii: "_") let asciiZero = UInt8(ascii: "0") let asciiOne = UInt8(ascii: "1") let asciiNine = UInt8(ascii: "9") -let asciiDigits = asciiZero ... asciiNine +let asciiDigits = asciiZero...asciiNine let asciiDquote = UInt8(ascii: "\"") let asciiColon = UInt8(ascii: ":") let asciiSemicolon = UInt8(ascii: ";") @@ -48,5 +48,5 @@ let asciiCapitalA = UInt8(ascii: "A") let asciiCapitalZ = UInt8(ascii: "Z") let asciiLowerA = UInt8(ascii: "a") let asciiLowerZ = UInt8(ascii: "z") -let asciiCapitals = asciiCapitalA ... asciiCapitalZ -let asciiLowercases = asciiLowerA ... asciiLowerZ +let asciiCapitals = asciiCapitalA...asciiCapitalZ +let asciiLowercases = asciiLowerA...asciiLowerZ diff --git a/Sources/RawStructuredFieldValues/ComponentTypes.swift b/Sources/RawStructuredFieldValues/ComponentTypes.swift index da4cac1..2b7ebb5 100644 --- a/Sources/RawStructuredFieldValues/ComponentTypes.swift +++ b/Sources/RawStructuredFieldValues/ComponentTypes.swift @@ -378,12 +378,12 @@ extension String { // / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" // / DIGIT / ALPHA // - // The following insane case statement covers this. Tokens suck. + // The following unfortunate case statement covers this. Tokens; not even once. case asciiExclamationMark, asciiOctothorpe, asciiDollar, asciiPercent, - asciiAmpersand, asciiSquote, asciiAsterisk, asciiPlus, asciiDash, - asciiPeriod, asciiCaret, asciiUnderscore, asciiBacktick, asciiPipe, - asciiTilde, asciiDigits, asciiCapitals, asciiLowercases, - asciiColon, asciiSlash: + asciiAmpersand, asciiSquote, asciiAsterisk, asciiPlus, asciiDash, + asciiPeriod, asciiCaret, asciiUnderscore, asciiBacktick, asciiPipe, + asciiTilde, asciiDigits, asciiCapitals, asciiLowercases, + asciiColon, asciiSlash: // Good () default: diff --git a/Sources/RawStructuredFieldValues/FieldParser.swift b/Sources/RawStructuredFieldValues/FieldParser.swift index 1959782..e2467b8 100644 --- a/Sources/RawStructuredFieldValues/FieldParser.swift +++ b/Sources/RawStructuredFieldValues/FieldParser.swift @@ -373,7 +373,7 @@ extension StructuredFieldValueParser { // Unquoted dquote, this is the end of the string. endIndex = index break loop - case 0x00 ... 0x1F, 0x7F...: + case 0x00...0x1F, 0x7F...: // Forbidden bytes in string: string must be VCHAR and SP. throw StructuredHeaderError.invalidString default: @@ -388,7 +388,7 @@ extension StructuredFieldValueParser { if endIndex == self.underlyingData.endIndex { throw StructuredHeaderError.invalidString } - let stringSlice = self.underlyingData[self.underlyingData.startIndex ..< index] + let stringSlice = self.underlyingData[self.underlyingData.startIndex.. RFC9651BareItem { - assert(asciiCapitals.contains(self.underlyingData.first!) || asciiLowercases.contains(self.underlyingData.first!) || self.underlyingData.first! == asciiAsterisk) + assert( + asciiCapitals.contains(self.underlyingData.first!) || asciiLowercases.contains(self.underlyingData.first!) + || self.underlyingData.first! == asciiAsterisk + ) var index = self.underlyingData.startIndex loop: while index < self.underlyingData.endIndex { @@ -461,12 +464,12 @@ extension StructuredFieldValueParser { // / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" // / DIGIT / ALPHA // - // The following insane case statement covers this. Tokens suck. + // The following unfortunate case statement covers this. Tokens; not even once. case asciiExclamationMark, asciiOctothorpe, asciiDollar, asciiPercent, - asciiAmpersand, asciiSquote, asciiAsterisk, asciiPlus, asciiDash, - asciiPeriod, asciiCaret, asciiUnderscore, asciiBacktick, asciiPipe, - asciiTilde, asciiDigits, asciiCapitals, asciiLowercases, - asciiColon, asciiSlash: + asciiAmpersand, asciiSquote, asciiAsterisk, asciiPlus, asciiDash, + asciiPeriod, asciiCaret, asciiUnderscore, asciiBacktick, asciiPipe, + asciiTilde, asciiDigits, asciiCapitals, asciiLowercases, + asciiColon, asciiSlash: // Good, consume self.underlyingData.formIndex(after: &index) default: @@ -551,7 +554,8 @@ extension RandomAccessCollection where Element == UInt8, SubSequence == Self { extension String { // This is the slow path, so we never inline this. @inline(never) - fileprivate static func decodingEscapes(_ bytes: Bytes, escapes: Int) -> String where Bytes.Element == UInt8 { + fileprivate static func decodingEscapes(_ bytes: Bytes, escapes: Int) -> String + where Bytes.Element == UInt8 { // We assume the string is previously validated, so the escapes are easily removed. See the doc comment for // `StrippingStringEscapesCollection` for more details on what we're doing here. let unescapedBytes = StrippingStringEscapesCollection(bytes, escapes: escapes) @@ -574,7 +578,8 @@ extension String { /// Until this issue is fixed (https://bugs.swift.org/browse/SR-13111) we take a different approach: we use /// `String.init(unsafeUninitializedCapacity:initializingWith)`. This is an unsafe function, so to reduce the unsafety as much /// as possible we define this safe wrapping Collection and then use `copyBytes` to implement the initialization. -private struct StrippingStringEscapesCollection where BaseCollection.Element == UInt8 { +private struct StrippingStringEscapesCollection +where BaseCollection.Element == UInt8 { private var base: BaseCollection private var escapes: UInt diff --git a/Sources/RawStructuredFieldValues/FieldSerializer.swift b/Sources/RawStructuredFieldValues/FieldSerializer.swift index 11e76b2..964ecdb 100644 --- a/Sources/RawStructuredFieldValues/FieldSerializer.swift +++ b/Sources/RawStructuredFieldValues/FieldSerializer.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -private let validIntegerRange = Int64(-999_999_999_999_999) ... Int64(999_999_999_999_999) +private let validIntegerRange = Int64(-999_999_999_999_999)...Int64(999_999_999_999_999) /// A `StructuredFieldValueSerializer` is the basic parsing object for structured header field values. public struct StructuredFieldValueSerializer: Sendable { @@ -45,7 +45,7 @@ extension StructuredFieldValueSerializer { /// Writes a structured list header field value. /// /// - parameters: - /// - root: The list object. + /// - list: The list object. /// - throws: If the list could not be serialized. /// - returns: The bytes of the serialized header field value. public mutating func writeListFieldValue(_ list: [ItemOrInnerList]) throws -> [UInt8] { @@ -63,7 +63,7 @@ extension StructuredFieldValueSerializer { /// Writes a structured item header field value. /// /// - parameters: - /// - root: The item. + /// - item: The item. /// - throws: If the item could not be serialized. /// - returns: The bytes of the serialized header field value. public mutating func writeItemFieldValue(_ item: Item) throws -> [UInt8] { @@ -179,7 +179,7 @@ extension StructuredFieldValueSerializer { self.data.append(contentsOf: String(decimal).utf8) case .string(let string): let bytes = string.utf8 - guard bytes.allSatisfy({ !(0x00 ... 0x1F).contains($0) && $0 != 0x7F && $0 < 0x80 }) else { + guard bytes.allSatisfy({ !(0x00...0x1F).contains($0) && $0 != 0x7F && $0 < 0x80 }) else { throw StructuredHeaderError.invalidString } self.data.append(asciiDquote) @@ -233,7 +233,7 @@ extension String { let validKey = utf8View.dropFirst().allSatisfy { switch $0 { case asciiLowercases, asciiDigits, asciiUnderscore, - asciiDash, asciiPeriod, asciiAsterisk: + asciiDash, asciiPeriod, asciiAsterisk: return true default: return false diff --git a/Sources/RawStructuredFieldValues/PseudoDecimal.swift b/Sources/RawStructuredFieldValues/PseudoDecimal.swift index d5a6b63..e3a9b75 100644 --- a/Sources/RawStructuredFieldValues/PseudoDecimal.swift +++ b/Sources/RawStructuredFieldValues/PseudoDecimal.swift @@ -114,9 +114,9 @@ public struct PseudoDecimal: Hashable, Sendable { // on the exponent. switch exponent { case 0 where mantissa.magnitude <= 999_999_999_999, - -1 where mantissa.magnitude <= 9_999_999_999_999, - -2 where mantissa.magnitude <= 99_999_999_999_999, - -3 where mantissa.magnitude <= 999_999_999_999_999: + -1 where mantissa.magnitude <= 9_999_999_999_999, + -2 where mantissa.magnitude <= 99_999_999_999_999, + -3 where mantissa.magnitude <= 999_999_999_999_999: // All acceptable () default: @@ -128,7 +128,9 @@ public struct PseudoDecimal: Hashable, Sendable { do { try Self.validate(mantissa: mantissa, exponent: exponent) } catch { - preconditionFailure("Invalid value for structured header decimal: mantissa \(mantissa) exponent \(exponent)") + preconditionFailure( + "Invalid value for structured header decimal: mantissa \(mantissa) exponent \(exponent)" + ) } } diff --git a/Sources/StructuredFieldValues/Decoder/BareInnerListDecoder.swift b/Sources/StructuredFieldValues/Decoder/BareInnerListDecoder.swift index 0d3cefb..7f12f3e 100644 --- a/Sources/StructuredFieldValues/Decoder/BareInnerListDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/BareInnerListDecoder.swift @@ -77,7 +77,8 @@ extension BareInnerListDecoder: UnkeyedDecodingContainer { } } - mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer + where NestedKey: CodingKey { // This is a request to decode a full item. We decode the next entry and increment the index. guard !self.isAtEnd else { throw StructuredHeaderError.indexOutOfRange diff --git a/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift b/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift index 08f139b..d287a0e 100644 --- a/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift @@ -114,9 +114,11 @@ extension BareItemDecoder: SingleValueDecodingContainer { throw StructuredHeaderError.invalidTypeForItem } - return Decimal(sign: pseudoDecimal.mantissa > 0 ? .plus : .minus, - exponent: Int(pseudoDecimal.exponent), - significand: Decimal(pseudoDecimal.mantissa.magnitude)) + return Decimal( + sign: pseudoDecimal.mantissa > 0 ? .plus : .minus, + exponent: Int(pseudoDecimal.exponent), + significand: Decimal(pseudoDecimal.mantissa.magnitude) + ) } func decodeNil() -> Bool { diff --git a/Sources/StructuredFieldValues/Decoder/DictionaryKeyedContainer.swift b/Sources/StructuredFieldValues/Decoder/DictionaryKeyedContainer.swift index decb5f2..85f2459 100644 --- a/Sources/StructuredFieldValues/Decoder/DictionaryKeyedContainer.swift +++ b/Sources/StructuredFieldValues/Decoder/DictionaryKeyedContainer.swift @@ -60,7 +60,10 @@ extension DictionaryKeyedContainer: KeyedDecodingContainerProtocol { } } - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: Key + ) throws -> KeyedDecodingContainer { try self.decoder.push(_StructuredHeaderCodingKey(key, keyDecodingStrategy: self.decoder.keyDecodingStrategy)) defer { self.decoder.pop() diff --git a/Sources/StructuredFieldValues/Decoder/KeyedInnerListDecoder.swift b/Sources/StructuredFieldValues/Decoder/KeyedInnerListDecoder.swift index b3f65b4..3a55379 100644 --- a/Sources/StructuredFieldValues/Decoder/KeyedInnerListDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/KeyedInnerListDecoder.swift @@ -65,7 +65,10 @@ extension KeyedInnerListDecoder: KeyedDecodingContainerProtocol { } } - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: Key + ) throws -> KeyedDecodingContainer { try self.decoder.push(_StructuredHeaderCodingKey(key, keyDecodingStrategy: self.decoder.keyDecodingStrategy)) defer { self.decoder.pop() diff --git a/Sources/StructuredFieldValues/Decoder/KeyedItemDecoder.swift b/Sources/StructuredFieldValues/Decoder/KeyedItemDecoder.swift index 7d9d244..46ad78b 100644 --- a/Sources/StructuredFieldValues/Decoder/KeyedItemDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/KeyedItemDecoder.swift @@ -65,7 +65,10 @@ extension KeyedItemDecoder: KeyedDecodingContainerProtocol { } } - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: Key + ) throws -> KeyedDecodingContainer { try self.decoder.push(_StructuredHeaderCodingKey(key, keyDecodingStrategy: self.decoder.keyDecodingStrategy)) defer { self.decoder.pop() diff --git a/Sources/StructuredFieldValues/Decoder/KeyedTopLevelListDecoder.swift b/Sources/StructuredFieldValues/Decoder/KeyedTopLevelListDecoder.swift index 19a622a..c06e467 100644 --- a/Sources/StructuredFieldValues/Decoder/KeyedTopLevelListDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/KeyedTopLevelListDecoder.swift @@ -65,7 +65,10 @@ extension KeyedTopLevelListDecoder: KeyedDecodingContainerProtocol { } } - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: Key + ) throws -> KeyedDecodingContainer { try self.decoder.push(_StructuredHeaderCodingKey(key, keyDecodingStrategy: self.decoder.keyDecodingStrategy)) defer { self.decoder.pop() diff --git a/Sources/StructuredFieldValues/Decoder/ParametersDecoder.swift b/Sources/StructuredFieldValues/Decoder/ParametersDecoder.swift index 19bdc0c..653ad48 100644 --- a/Sources/StructuredFieldValues/Decoder/ParametersDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/ParametersDecoder.swift @@ -60,7 +60,10 @@ extension ParametersDecoder: KeyedDecodingContainerProtocol { } } - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + func nestedContainer( + keyedBy type: NestedKey.Type, + forKey key: Key + ) throws -> KeyedDecodingContainer { try self.decoder.push(_StructuredHeaderCodingKey(key, keyDecodingStrategy: self.decoder.keyDecodingStrategy)) defer { self.decoder.pop() diff --git a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift index 91a076c..267b20b 100644 --- a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift @@ -46,7 +46,10 @@ extension StructuredFieldValueDecoder { /// - data: The bytes of the structured header field. /// - throws: If the header field could not be parsed, or could not be decoded. /// - returns: An object of type `StructuredField`. - public func decode(_ type: StructuredField.Type = StructuredField.self, from data: BaseData) throws -> StructuredField where BaseData.Element == UInt8 { + public func decode( + _ type: StructuredField.Type = StructuredField.self, + from data: BaseData + ) throws -> StructuredField where BaseData.Element == UInt8 { switch StructuredField.structuredFieldType { case .item: return try self.decodeItemField(from: data) @@ -64,7 +67,10 @@ extension StructuredFieldValueDecoder { /// - data: The bytes of the structured header field. /// - throws: If the header field could not be parsed, or could not be decoded. /// - returns: An object of type `StructuredField`. - private func decodeDictionaryField(_ type: StructuredField.Type = StructuredField.self, from data: BaseData) throws -> StructuredField where BaseData.Element == UInt8 { + private func decodeDictionaryField( + _ type: StructuredField.Type = StructuredField.self, + from data: BaseData + ) throws -> StructuredField where BaseData.Element == UInt8 { let parser = StructuredFieldValueParser(data) let decoder = _StructuredFieldDecoder(parser, keyDecodingStrategy: self.keyDecodingStrategy) try decoder.parseDictionaryField() @@ -78,7 +84,10 @@ extension StructuredFieldValueDecoder { /// - data: The bytes of the structured header field. /// - throws: If the header field could not be parsed, or could not be decoded. /// - returns: An object of type `StructuredField`. - private func decodeListField(_ type: StructuredField.Type = StructuredField.self, from data: BaseData) throws -> StructuredField where BaseData.Element == UInt8 { + private func decodeListField( + _ type: StructuredField.Type = StructuredField.self, + from data: BaseData + ) throws -> StructuredField where BaseData.Element == UInt8 { let parser = StructuredFieldValueParser(data) let decoder = _StructuredFieldDecoder(parser, keyDecodingStrategy: self.keyDecodingStrategy) try decoder.parseListField() @@ -92,7 +101,10 @@ extension StructuredFieldValueDecoder { /// - data: The bytes of the structured header field. /// - throws: If the header field could not be parsed, or could not be decoded. /// - returns: An object of type `StructuredField`. - private func decodeItemField(_ type: StructuredField.Type = StructuredField.self, from data: BaseData) throws -> StructuredField where BaseData.Element == UInt8 { + private func decodeItemField( + _ type: StructuredField.Type = StructuredField.self, + from data: BaseData + ) throws -> StructuredField where BaseData.Element == UInt8 { let parser = StructuredFieldValueParser(data) let decoder = _StructuredFieldDecoder(parser, keyDecodingStrategy: self.keyDecodingStrategy) try decoder.parseItemField() @@ -120,7 +132,10 @@ class _StructuredFieldDecoder where BaseData.E var keyDecodingStrategy: StructuredFieldValueDecoder.KeyDecodingStrategy? - init(_ parser: StructuredFieldValueParser, keyDecodingStrategy: StructuredFieldValueDecoder.KeyDecodingStrategy?) { + init( + _ parser: StructuredFieldValueParser, + keyDecodingStrategy: StructuredFieldValueDecoder.KeyDecodingStrategy? + ) { self.parser = parser self._codingStack = [] self.keyDecodingStrategy = keyDecodingStrategy diff --git a/Sources/StructuredFieldValues/Decoder/TopLevelListDecoder.swift b/Sources/StructuredFieldValues/Decoder/TopLevelListDecoder.swift index 9092f0e..62e3688 100644 --- a/Sources/StructuredFieldValues/Decoder/TopLevelListDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/TopLevelListDecoder.swift @@ -77,7 +77,8 @@ extension TopLevelListDecoder: UnkeyedDecodingContainer { } } - mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer + where NestedKey: CodingKey { // This is a request to decode a full item. We decode the next entry and increment the index. guard !self.isAtEnd else { throw StructuredHeaderError.indexOutOfRange diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldKeyedEncodingContainer.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldKeyedEncodingContainer.swift index 40d20a8..bc5ff8c 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldKeyedEncodingContainer.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldKeyedEncodingContainer.swift @@ -93,8 +93,11 @@ extension StructuredFieldKeyedEncodingContainer: KeyedEncodingContainerProtocol try self.encoder.encode(value, forKey: key.stringValue) } - mutating func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer where NestedKey: CodingKey { - return self.encoder.container(keyedBy: keyType) + mutating func nestedContainer( + keyedBy keyType: NestedKey.Type, + forKey key: Key + ) -> KeyedEncodingContainer where NestedKey: CodingKey { + self.encoder.container(keyedBy: keyType) } mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldUnkeyedEncodingContainer.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldUnkeyedEncodingContainer.swift index 1873bdd..4bafe3f 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldUnkeyedEncodingContainer.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldUnkeyedEncodingContainer.swift @@ -97,8 +97,9 @@ extension StructuredFieldUnkeyedEncodingContainer: UnkeyedEncodingContainer { try self.encoder.append(value) } - mutating func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer where NestedKey: CodingKey { - return self.encoder.container(keyedBy: keyType) + mutating func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer + where NestedKey: CodingKey { + self.encoder.container(keyedBy: keyType) } mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift index 59a881e..1ffe2f1 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift @@ -103,11 +103,16 @@ class _StructuredFieldEncoder { internal var keyEncodingStrategy: StructuredFieldValueEncoder.KeyEncodingStrategy? - init(_ serializer: StructuredFieldValueSerializer, keyEncodingStrategy: StructuredFieldValueEncoder.KeyEncodingStrategy?) { + init( + _ serializer: StructuredFieldValueSerializer, + keyEncodingStrategy: StructuredFieldValueEncoder.KeyEncodingStrategy? + ) { self.serializer = serializer self._codingPath = [] self.keyEncodingStrategy = keyEncodingStrategy - self.currentStackEntry = CodingStackEntry(key: .init(stringValue: ""), storage: .itemHeader) // This default doesn't matter right now. + + // This default doesn't matter right now. + self.currentStackEntry = CodingStackEntry(key: .init(stringValue: ""), storage: .itemHeader) } fileprivate func encodeDictionaryField(_ data: StructuredField) throws -> [UInt8] { @@ -121,7 +126,7 @@ class _StructuredFieldEncoder { // No encoding happened. return [] case .listHeader, .list, .itemHeader, .item, .bareInnerList, .innerList, - .parameters, .itemOrInnerList: + .parameters, .itemOrInnerList: throw StructuredHeaderError.invalidTypeForItem } } @@ -137,7 +142,7 @@ class _StructuredFieldEncoder { // No encoding happened return [] case .dictionaryHeader, .dictionary, .itemHeader, .item, .bareInnerList, .innerList, - .parameters, .itemOrInnerList: + .parameters, .itemOrInnerList: throw StructuredHeaderError.invalidTypeForItem } } @@ -166,7 +171,7 @@ class _StructuredFieldEncoder { // No encoding happened return [] case .dictionaryHeader, .dictionary, .listHeader, .list, .bareInnerList, .innerList, - .parameters, .itemOrInnerList: + .parameters, .itemOrInnerList: throw StructuredHeaderError.invalidTypeForItem } } @@ -197,7 +202,7 @@ extension _StructuredFieldEncoder: Encoder { } func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { - return KeyedEncodingContainer(StructuredFieldKeyedEncodingContainer(encoder: self)) + KeyedEncodingContainer(StructuredFieldKeyedEncodingContainer(encoder: self)) } func unkeyedContainer() -> UnkeyedEncodingContainer { @@ -281,7 +286,7 @@ extension _StructuredFieldEncoder: SingleValueEncodingContainer { } func encode(_ data: Decimal) throws { - let significand = (data.significand.magnitude as NSNumber).intValue // Yes, really. + let significand = (data.significand.magnitude as NSNumber).intValue // Yes, really. guard let exponent = Int8(exactly: data.exponent) else { throw StructuredHeaderError.invalidIntegerOrDecimal } @@ -438,7 +443,7 @@ extension _StructuredFieldEncoder { } func append(_ value: Decimal) throws { - let significand = (value.significand.magnitude as NSNumber).intValue // Yes, really. + let significand = (value.significand.magnitude as NSNumber).intValue // Yes, really. guard let exponent = Int8(exactly: value.exponent) else { throw StructuredHeaderError.invalidIntegerOrDecimal } @@ -601,11 +606,14 @@ extension _StructuredFieldEncoder { func encode(_ value: Data, forKey key: String) throws { let key = self.sanitizeKey(key) - try self.currentStackEntry.storage.insertBareItem(.undecodedByteSequence(value.base64EncodedString()), atKey: key) + try self.currentStackEntry.storage.insertBareItem( + .undecodedByteSequence(value.base64EncodedString()), + atKey: key + ) } func encode(_ value: Decimal, forKey key: String) throws { - let significand = (value.significand.magnitude as NSNumber).intValue // Yes, really. + let significand = (value.significand.magnitude as NSNumber).intValue // Yes, really. guard let exponent = Int8(exactly: value.exponent) else { throw StructuredHeaderError.invalidIntegerOrDecimal } @@ -715,7 +723,7 @@ extension _StructuredFieldEncoder { } case .list, .itemHeader, .bareInnerList, - .parameters: + .parameters: throw StructuredHeaderError.invalidTypeForItem } } @@ -914,10 +922,12 @@ extension _StructuredFieldEncoder { case .itemOrInnerList(let params): // This is an inner list. - self = .innerList(InnerList(bareInnerList: [Item(bareItem: bareItem, parameters: [:])], parameters: params)) + self = .innerList( + InnerList(bareInnerList: [Item(bareItem: bareItem, parameters: [:])], parameters: params) + ) case .dictionaryHeader, .dictionary, .itemHeader, .item, - .parameters: + .parameters: throw StructuredHeaderError.invalidTypeForItem } } diff --git a/Sources/sh-parser/main.swift b/Sources/sh-parser/main.swift index bbf978f..75deb27 100644 --- a/Sources/sh-parser/main.swift +++ b/Sources/sh-parser/main.swift @@ -163,8 +163,11 @@ extension RFC9651BareItem { case .undecodedByteSequence(let bytes): return "byte sequence \(bytes)" case .decimal(let decimal): - let d = Decimal(sign: decimal.mantissa > 0 ? .plus : .minus, - exponent: Int(decimal.exponent), significand: Decimal(decimal.mantissa)) + let d = Decimal( + sign: decimal.mantissa > 0 ? .plus : .minus, + exponent: Int(decimal.exponent), + significand: Decimal(decimal.mantissa) + ) return "decimal \(d)" case .date(let date): return "date \(date)" diff --git a/Tests/StructuredFieldValuesTests/Base32.swift b/Tests/StructuredFieldValuesTests/Base32.swift index 29c0ca9..588265f 100644 --- a/Tests/StructuredFieldValuesTests/Base32.swift +++ b/Tests/StructuredFieldValuesTests/Base32.swift @@ -25,7 +25,7 @@ extension Data { self = Data() for start in stride(from: data.startIndex, to: data.endIndex, by: 8) { - let bytes = data[start ..< (start + 8)] + let bytes = data[start..<(start + 8)] precondition(bytes.count == 8) var seenEquals = 0 @@ -60,7 +60,7 @@ extension Data { fatalError("Impossible equals count: \(seenEquals)") } - for byteNumber in (ignoredBytes ..< 5).reversed() { + for byteNumber in (ignoredBytes..<5).reversed() { let byte = UInt8(truncatingIfNeeded: rawValue >> (byteNumber * 8)) self.append(byte) } diff --git a/Tests/StructuredFieldValuesTests/Fixtures.swift b/Tests/StructuredFieldValuesTests/Fixtures.swift index 864c308..b647a9b 100644 --- a/Tests/StructuredFieldValuesTests/Fixtures.swift +++ b/Tests/StructuredFieldValuesTests/Fixtures.swift @@ -26,12 +26,18 @@ enum FixturesLoader { static var parsingFixtures: [StructuredHeaderTestFixture] { // ContentsOfDirectory can throw if it hits EINTR, just spin var files: [URL]? - for _ in 0 ..< 1000 { + for _ in 0..<1000 { do { - files = try FileManager.default.contentsOfDirectory(at: fixturesDirectory, includingPropertiesForKeys: nil, options: []) + files = try FileManager.default.contentsOfDirectory( + at: fixturesDirectory, + includingPropertiesForKeys: nil, + options: [] + ) break } catch let error as NSError { - guard let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError, underlyingError.domain == NSPOSIXErrorDomain, underlyingError.code == EINTR else { + guard let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError, + underlyingError.domain == NSPOSIXErrorDomain, underlyingError.code == EINTR + else { fatalError("\(error)") } // Ok, we'll continue @@ -52,12 +58,18 @@ enum FixturesLoader { static var serializingFixtures: [StructuredHeaderTestFixture] { // ContentsOfDirectory can throw if it hits EINTR, just spin var files: [URL]? - for _ in 0 ..< 1000 { + for _ in 0..<1000 { do { - files = try FileManager.default.contentsOfDirectory(at: serializationFixturesDirectory, includingPropertiesForKeys: nil, options: []) + files = try FileManager.default.contentsOfDirectory( + at: serializationFixturesDirectory, + includingPropertiesForKeys: nil, + options: [] + ) break } catch let error as NSError { - guard let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError, underlyingError.domain == NSPOSIXErrorDomain, underlyingError.code == EINTR else { + guard let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError, + underlyingError.domain == NSPOSIXErrorDomain, underlyingError.code == EINTR + else { fatalError("\(error)") } // Ok, we'll continue diff --git a/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift b/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift index 3198aca..645d52e 100644 --- a/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift +++ b/Tests/StructuredFieldValuesTests/StructuredFieldDecoderTests.swift @@ -88,12 +88,20 @@ struct ListyDictionaryField: StructuredFieldValue, Equatable { final class StructuredFieldDecoderTests: XCTestCase { func testSimpleCodableDecode() throws { - let headerField = "primary=bar;q=1.0, secondary=baz;q=0.5;fallback=last, acceptablejurisdictions=(AU;q=1.0 GB;q=0.9 FR);fallback=\"primary\"" + let headerField = + "primary=bar;q=1.0, secondary=baz;q=0.5;fallback=last, acceptablejurisdictions=(AU;q=1.0 GB;q=0.9 FR);fallback=\"primary\"" let parsed = try StructuredFieldValueDecoder().decode(ListyDictionaryField.self, from: Array(headerField.utf8)) let expected = ListyDictionaryField( primary: .init(item: "bar", parameters: .init(q: 1, fallback: nil)), secondary: .init(item: "baz", parameters: .init(q: 0.5, fallback: "last")), - acceptablejurisdictions: .init(items: [.init(item: "AU", parameters: .init(q: 1, fallback: nil)), .init(item: "GB", parameters: .init(q: 0.9, fallback: nil)), .init(item: "FR", parameters: .init(q: nil, fallback: nil))], parameters: .init(q: nil, fallback: "primary")) + acceptablejurisdictions: .init( + items: [ + .init(item: "AU", parameters: .init(q: 1, fallback: nil)), + .init(item: "GB", parameters: .init(q: 0.9, fallback: nil)), + .init(item: "FR", parameters: .init(q: nil, fallback: nil)), + ], + parameters: .init(q: nil, fallback: "primary") + ) ) XCTAssertEqual(parsed, expected) } @@ -106,9 +114,17 @@ final class StructuredFieldDecoderTests: XCTestCase { var secondary: String var acceptablejurisdictions: [String] } - let headerField = "primary=bar;q=1.0, secondary=baz;q=0.5;fallback=last, acceptablejurisdictions=(AU;q=1.0 GB;q=0.9 FR);fallback=\"primary\"" - let parsed = try StructuredFieldValueDecoder().decode(ListyDictionaryNoParams.self, from: Array(headerField.utf8)) - let expected = ListyDictionaryNoParams(primary: "bar", secondary: "baz", acceptablejurisdictions: ["AU", "GB", "FR"]) + let headerField = + "primary=bar;q=1.0, secondary=baz;q=0.5;fallback=last, acceptablejurisdictions=(AU;q=1.0 GB;q=0.9 FR);fallback=\"primary\"" + let parsed = try StructuredFieldValueDecoder().decode( + ListyDictionaryNoParams.self, + from: Array(headerField.utf8) + ) + let expected = ListyDictionaryNoParams( + primary: "bar", + secondary: "baz", + acceptablejurisdictions: ["AU", "GB", "FR"] + ) XCTAssertEqual(parsed, expected) } @@ -135,13 +151,27 @@ final class StructuredFieldDecoderTests: XCTestCase { let headerField = "-999999999999999;bar=baz" let expected = ItemField(Int64(-999_999_999_999_999)) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) XCTAssertEqual(expected, try StructuredFieldValueDecoder().decode(from: Array(headerField.utf8))) } @@ -156,18 +186,42 @@ final class StructuredFieldDecoderTests: XCTestCase { let headerField = "gzip" let intField = "5" - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8))) - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(intField.utf8))) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(headerField.utf8)) + ) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(ItemField.self, from: Array(intField.utf8)) + ) } func testDecodingTopLevelItemWithParameters() throws { @@ -241,7 +295,9 @@ final class StructuredFieldDecoderTests: XCTestCase { } let headerField = "innerlist=x" - XCTAssertThrowsError(try StructuredFieldValueDecoder().decode(MissingInnerList.self, from: Array(headerField.utf8))) + XCTAssertThrowsError( + try StructuredFieldValueDecoder().decode(MissingInnerList.self, from: Array(headerField.utf8)) + ) } func testDecodingBinaryAsTopLevelData() throws { @@ -318,7 +374,12 @@ final class StructuredFieldDecoderTests: XCTestCase { } let headerField = "(:AQIDBA==: :BQYHCA==:);foo, (:AQIDBA==: :BQYHCA==:);foo" XCTAssertEqual( - List(Array(repeating: ListField(items: [Data([1, 2, 3, 4]), Data([5, 6, 7, 8])], parameters: ["foo": true]), count: 2)), + List( + Array( + repeating: ListField(items: [Data([1, 2, 3, 4]), Data([5, 6, 7, 8])], parameters: ["foo": true]), + count: 2 + ) + ), try StructuredFieldValueDecoder().decode(from: Array(headerField.utf8)) ) } @@ -403,7 +464,15 @@ final class StructuredFieldDecoderTests: XCTestCase { } let headerField = "(987654321.123 123456789.321);foo, (987654321.123 123456789.321);foo" XCTAssertEqual( - List(Array(repeating: ListField(items: [Decimal(string: "987654321.123")!, Decimal(string: "123456789.321")!], parameters: ["foo": true]), count: 2)), + List( + Array( + repeating: ListField( + items: [Decimal(string: "987654321.123")!, Decimal(string: "123456789.321")!], + parameters: ["foo": true] + ), + count: 2 + ) + ), try StructuredFieldValueDecoder().decode(from: Array(headerField.utf8)) ) } diff --git a/Tests/StructuredFieldValuesTests/StructuredFieldEncoderTests.swift b/Tests/StructuredFieldValuesTests/StructuredFieldEncoderTests.swift index 1c86f24..e660fcd 100644 --- a/Tests/StructuredFieldValuesTests/StructuredFieldEncoderTests.swift +++ b/Tests/StructuredFieldValuesTests/StructuredFieldEncoderTests.swift @@ -16,6 +16,7 @@ import RawStructuredFieldValues import StructuredFieldValues import XCTest +// swift-format-ignore: DontRepeatTypeInStaticProperties final class StructuredFieldEncoderTests: XCTestCase { func testSimpleItemHeaderEncodeBareItem() throws { // We're going to try encoding a few bare items as item headers to confirm @@ -61,7 +62,10 @@ final class StructuredFieldEncoderTests: XCTestCase { XCTAssertEqual(Array("?0;x=?0".utf8), try encoder.encode(KeyedItem(item: false, parameters: ["x": false]))) // String and token - XCTAssertEqual(Array("\"hello, world\"".utf8), try encoder.encode(KeyedItem(item: "hello, world", parameters: [:]))) + XCTAssertEqual( + Array("\"hello, world\"".utf8), + try encoder.encode(KeyedItem(item: "hello, world", parameters: [:])) + ) XCTAssertEqual(Array("gzip;x".utf8), try encoder.encode(KeyedItem(item: "gzip", parameters: ["x": true]))) // Integer @@ -69,14 +73,29 @@ final class StructuredFieldEncoderTests: XCTestCase { XCTAssertEqual(Array("-10".utf8), try encoder.encode(KeyedItem(item: Int32(-10), parameters: [:]))) // Decimal - XCTAssertEqual(Array("102.2;y=?0".utf8), try encoder.encode(KeyedItem(item: Float(102.2), parameters: ["y": false]))) + XCTAssertEqual( + Array("102.2;y=?0".utf8), + try encoder.encode(KeyedItem(item: Float(102.2), parameters: ["y": false])) + ) XCTAssertEqual(Array("-166.66".utf8), try encoder.encode(KeyedItem(item: Double(-166.66), parameters: [:]))) - XCTAssertEqual(Array("987654321.123;y=?0".utf8), try encoder.encode(KeyedItem(item: Decimal(string: "987654321.123")!, parameters: ["y": false]))) - XCTAssertEqual(Array("-123456789.321".utf8), try encoder.encode(KeyedItem(item: Decimal(string: "-123456789.321")!, parameters: [:]))) + XCTAssertEqual( + Array("987654321.123;y=?0".utf8), + try encoder.encode(KeyedItem(item: Decimal(string: "987654321.123")!, parameters: ["y": false])) + ) + XCTAssertEqual( + Array("-123456789.321".utf8), + try encoder.encode(KeyedItem(item: Decimal(string: "-123456789.321")!, parameters: [:])) + ) // Binary - XCTAssertEqual(Array(":AQIDBA==:;y=?0".utf8), try encoder.encode(KeyedItem(item: Data([1, 2, 3, 4]), parameters: ["y": false]))) - XCTAssertEqual(Array(":AQIDBA==:".utf8), try encoder.encode(KeyedItem(item: Data([1, 2, 3, 4]), parameters: [:]))) + XCTAssertEqual( + Array(":AQIDBA==:;y=?0".utf8), + try encoder.encode(KeyedItem(item: Data([1, 2, 3, 4]), parameters: ["y": false])) + ) + XCTAssertEqual( + Array(":AQIDBA==:".utf8), + try encoder.encode(KeyedItem(item: Data([1, 2, 3, 4]), parameters: [:])) + ) } func testEncodeKeyedItemHeaderWithParamsAsStruct() throws { @@ -93,9 +112,18 @@ final class StructuredFieldEncoderTests: XCTestCase { let encoder = StructuredFieldValueEncoder() - XCTAssertEqual(Array("gzip;x;q=0.8".utf8), try encoder.encode(Field(item: "gzip", parameters: Parameters(x: true, q: 0.8)))) - XCTAssertEqual(Array("deflate;q=0.6".utf8), try encoder.encode(Field(item: "deflate", parameters: Parameters(x: nil, q: 0.6)))) - XCTAssertEqual(Array("zlib".utf8), try encoder.encode(Field(item: "zlib", parameters: Parameters(x: nil, q: nil)))) + XCTAssertEqual( + Array("gzip;x;q=0.8".utf8), + try encoder.encode(Field(item: "gzip", parameters: Parameters(x: true, q: 0.8))) + ) + XCTAssertEqual( + Array("deflate;q=0.6".utf8), + try encoder.encode(Field(item: "deflate", parameters: Parameters(x: nil, q: 0.6))) + ) + XCTAssertEqual( + Array("zlib".utf8), + try encoder.encode(Field(item: "zlib", parameters: Parameters(x: nil, q: nil))) + ) } func testEncodeSimpleDictionary() throws { @@ -125,31 +153,42 @@ final class StructuredFieldEncoderTests: XCTestCase { let encoder = StructuredFieldValueEncoder() - XCTAssertEqual(Array("x=66;q=0.8".utf8), - try encoder.encode(DictionaryField(x: Field(item: 66, parameters: ["q": 0.8])))) + XCTAssertEqual( + Array("x=66;q=0.8".utf8), + try encoder.encode(DictionaryField(x: Field(item: 66, parameters: ["q": 0.8]))) + ) } func testSimpleListField() throws { let encoder = StructuredFieldValueEncoder() // Bool - XCTAssertEqual(Array("?1, ?0, ?1".utf8), - try encoder.encode(List([true, false, true]))) + XCTAssertEqual( + Array("?1, ?0, ?1".utf8), + try encoder.encode(List([true, false, true])) + ) // String and token - XCTAssertEqual(Array("\"hello, world\", gzip".utf8), - try encoder.encode(List(["hello, world", "gzip"]))) + XCTAssertEqual( + Array("\"hello, world\", gzip".utf8), + try encoder.encode(List(["hello, world", "gzip"])) + ) // Integer XCTAssertEqual(Array("10, -10".utf8), try encoder.encode(List([Int16(10), Int16(-10)]))) // Decimal XCTAssertEqual(Array("102.2, -166.66".utf8), try encoder.encode(List([Float(102.2), Float(-166.66)]))) - XCTAssertEqual(Array("123456789.321, -987654321.123".utf8), try encoder.encode(List([Decimal(string: "123456789.321")!, Decimal(string: "-987654321.123")!]))) + XCTAssertEqual( + Array("123456789.321, -987654321.123".utf8), + try encoder.encode(List([Decimal(string: "123456789.321")!, Decimal(string: "-987654321.123")!])) + ) // Binary - XCTAssertEqual(Array(":AQIDBA==:, :BQYHCA==:".utf8), - try encoder.encode(List([Data([1, 2, 3, 4]), Data([5, 6, 7, 8])]))) + XCTAssertEqual( + Array(":AQIDBA==:, :BQYHCA==:".utf8), + try encoder.encode(List([Data([1, 2, 3, 4]), Data([5, 6, 7, 8])])) + ) } func testListFieldInnerItemsWithDict() throws { @@ -159,11 +198,15 @@ final class StructuredFieldEncoderTests: XCTestCase { } let encoder = StructuredFieldValueEncoder() - let header = [Item(parameters: ["q": 0.8], item: "gzip"), - Item(parameters: ["q": 0.6], item: "deflate")] + let header = [ + Item(parameters: ["q": 0.8], item: "gzip"), + Item(parameters: ["q": 0.6], item: "deflate"), + ] - XCTAssertEqual(Array("gzip;q=0.8, deflate;q=0.6".utf8), - try encoder.encode(List(header))) + XCTAssertEqual( + Array("gzip;q=0.8, deflate;q=0.6".utf8), + try encoder.encode(List(header)) + ) } func testListFieldInnerItemsWithObject() throws { @@ -177,11 +220,15 @@ final class StructuredFieldEncoderTests: XCTestCase { } let encoder = StructuredFieldValueEncoder() - let header = [Item(item: "gzip", parameters: Parameters(q: 0.8)), - Item(item: "deflate", parameters: Parameters(q: nil))] + let header = [ + Item(item: "gzip", parameters: Parameters(q: 0.8)), + Item(item: "deflate", parameters: Parameters(q: nil)), + ] - XCTAssertEqual(Array("gzip;q=0.8, deflate".utf8), - try encoder.encode(List(header))) + XCTAssertEqual( + Array("gzip;q=0.8, deflate".utf8), + try encoder.encode(List(header)) + ) } func testListFieldInnerListsBare() throws { @@ -197,8 +244,10 @@ final class StructuredFieldEncoderTests: XCTestCase { } let encoder = StructuredFieldValueEncoder() - let header = [Integers(items: [1, 2, 3], parameters: ["early": "yes"]), - Integers(items: [4, 5, 6], parameters: ["early": "no"])] + let header = [ + Integers(items: [1, 2, 3], parameters: ["early": "yes"]), + Integers(items: [4, 5, 6], parameters: ["early": "no"]), + ] XCTAssertEqual(Array("(1 2 3);early=yes, (4 5 6);early=no".utf8), try encoder.encode(List(header))) } @@ -219,8 +268,10 @@ final class StructuredFieldEncoderTests: XCTestCase { Item(item: 4, parameters: ["odd": false]), ], ] - XCTAssertEqual(Array("(1;odd 2;odd=?0), (3;odd 4;odd=?0)".utf8), - try encoder.encode(List(header))) + XCTAssertEqual( + Array("(1;odd 2;odd=?0), (3;odd 4;odd=?0)".utf8), + try encoder.encode(List(header)) + ) } func testListFieldExplicitInnerListsWithItemsWithParameters() throws { @@ -259,8 +310,10 @@ final class StructuredFieldEncoderTests: XCTestCase { parameters: FieldParams(sorted: false) ), ] - XCTAssertEqual(Array("(gzip;q=0.8 deflate;q=0.6);sorted, (zlib;q=0.4 br;q=1.0);sorted=?0".utf8), - try encoder.encode(List(header))) + XCTAssertEqual( + Array("(gzip;q=0.8 deflate;q=0.6);sorted, (zlib;q=0.4 br;q=1.0);sorted=?0".utf8), + try encoder.encode(List(header)) + ) } func testDictionaryFieldWithSimpleInnerLists() throws { @@ -272,8 +325,10 @@ final class StructuredFieldEncoderTests: XCTestCase { } let encoder = StructuredFieldValueEncoder() - XCTAssertEqual(Array("name=red, intensity=(1.0 0.0 0.0)".utf8), - try encoder.encode(Field(name: "red", color: nil, intensity: [1.0, 0.0, 0.0]))) + XCTAssertEqual( + Array("name=red, intensity=(1.0 0.0 0.0)".utf8), + try encoder.encode(Field(name: "red", color: nil, intensity: [1.0, 0.0, 0.0])) + ) } func testDictionaryFieldWithComplexInnerLists() throws { @@ -295,8 +350,10 @@ final class StructuredFieldEncoderTests: XCTestCase { let field = Field( green: Color(items: [0.0, 1.0, 0.0], parameters: ColorParameters(name: "green")) ) - XCTAssertEqual(Array("green=(0.0 1.0 0.0);name=green".utf8), - try encoder.encode(field)) + XCTAssertEqual( + Array("green=(0.0 1.0 0.0);name=green".utf8), + try encoder.encode(field) + ) } func testEmptyListField() throws { @@ -385,8 +442,10 @@ final class StructuredFieldEncoderTests: XCTestCase { var lowercaseEncoder = noStrategyEncoder lowercaseEncoder.keyEncodingStrategy = .lowercase - XCTAssertEqual(Array("allowall".utf8), - try lowercaseEncoder.encode(DictionaryField(allowAll: true))) + XCTAssertEqual( + Array("allowall".utf8), + try lowercaseEncoder.encode(DictionaryField(allowAll: true)) + ) } func testLowercaseKeysOnParameters() throws { @@ -417,19 +476,27 @@ final class StructuredFieldEncoderTests: XCTestCase { XCTAssertEqual(Array("1;allowall".utf8), try lowercaseEncoder.encode(item)) XCTAssertThrowsError(try noStrategyEncoder.encode(List([item, item]))) - XCTAssertEqual(Array("1;allowall, 1;allowall".utf8), - try lowercaseEncoder.encode(List([item, item]))) + XCTAssertEqual( + Array("1;allowall, 1;allowall".utf8), + try lowercaseEncoder.encode(List([item, item])) + ) XCTAssertThrowsError(try noStrategyEncoder.encode(List([list]))) - XCTAssertEqual(Array("(1 2);allowall".utf8), - try lowercaseEncoder.encode(List([list]))) + XCTAssertEqual( + Array("(1 2);allowall".utf8), + try lowercaseEncoder.encode(List([list])) + ) XCTAssertThrowsError(try noStrategyEncoder.encode(DictionaryField(["item": item]))) - XCTAssertEqual(Array("item=1;allowall".utf8), - try lowercaseEncoder.encode(DictionaryField(["item": item]))) + XCTAssertEqual( + Array("item=1;allowall".utf8), + try lowercaseEncoder.encode(DictionaryField(["item": item])) + ) XCTAssertThrowsError(try noStrategyEncoder.encode(DictionaryField(["list": list]))) - XCTAssertEqual(Array("list=(1 2);allowall".utf8), - try lowercaseEncoder.encode(DictionaryField(["list": list]))) + XCTAssertEqual( + Array("list=(1 2);allowall".utf8), + try lowercaseEncoder.encode(DictionaryField(["list": list])) + ) } } diff --git a/Tests/StructuredFieldValuesTests/StructuredFieldParserTests.swift b/Tests/StructuredFieldValuesTests/StructuredFieldParserTests.swift index 6749df4..5f40a86 100644 --- a/Tests/StructuredFieldValuesTests/StructuredFieldParserTests.swift +++ b/Tests/StructuredFieldValuesTests/StructuredFieldParserTests.swift @@ -26,20 +26,31 @@ final class StructuredFieldParserTests: XCTestCase { case item(Item) } - private func _validateBareItem(_ bareItem: RFC9651BareItem, against schema: JSONSchema, fixtureName: String) throws { + private func _validateBareItem(_ bareItem: RFC9651BareItem, against schema: JSONSchema, fixtureName: String) throws + { switch (bareItem, schema) { case (.integer(let baseInt), .integer(let jsonInt)): XCTAssertEqual(baseInt, jsonInt, "\(fixtureName): Got \(bareItem), expected \(schema)") case (.decimal(let baseDecimal), .double(let jsonDouble)): - XCTAssertEqual(String(baseDecimal), String(jsonDouble), "\(fixtureName): Got \(bareItem), expected \(schema)") + XCTAssertEqual( + String(baseDecimal), + String(jsonDouble), + "\(fixtureName): Got \(bareItem), expected \(schema)" + ) case (.decimal(let baseDecimal), .integer(let jsonInteger)): // Due to limits of Foundation's JSONSerialization, we can get types that decode as integers but are actually decimals. // We just cannot tell the difference here, so we tolerate this flexibility. - XCTAssertEqual(Double(baseDecimal), Double(jsonInteger), "\(fixtureName): Got \(bareItem), expected \(schema)") + XCTAssertEqual( + Double(baseDecimal), + Double(jsonInteger), + "\(fixtureName): Got \(bareItem), expected \(schema)" + ) case (.string(let baseString), .string(let jsonString)): XCTAssertEqual(baseString, jsonString, "\(fixtureName): Got \(bareItem), expected \(schema)") case (.token(let token), .dictionary(let typeDictionary)): - guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], case .string(let typeValue) = typeDictionary["value"] else { + guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], + case .string(let typeValue) = typeDictionary["value"] + else { XCTFail("\(fixtureName): Unexpected type dict \(typeDictionary)") return } @@ -47,7 +58,9 @@ final class StructuredFieldParserTests: XCTestCase { XCTAssertEqual(typeName, "token", "\(fixtureName): Expected type token, got type \(typeName)") XCTAssertEqual(typeValue, token, "\(fixtureName): Got \(token), expected \(typeValue)") case (.undecodedByteSequence(let binary), .dictionary(let typeDictionary)): - guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], case .string(let typeValue) = typeDictionary["value"] else { + guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], + case .string(let typeValue) = typeDictionary["value"] + else { XCTFail("\(fixtureName): Unexpected type dict \(typeDictionary)") return } @@ -57,11 +70,17 @@ final class StructuredFieldParserTests: XCTestCase { throw FixtureTestError.base64DecodingFailed } let decodedExpected = Data(base32Encoded: Data(typeValue.utf8)) - XCTAssertEqual(decodedValue, decodedExpected, "\(fixtureName): Got \(Array(decodedValue)), expected \(Array(decodedExpected))") + XCTAssertEqual( + decodedValue, + decodedExpected, + "\(fixtureName): Got \(Array(decodedValue)), expected \(Array(decodedExpected))" + ) case (.bool(let baseBool), .bool(let expectedBool)): XCTAssertEqual(baseBool, expectedBool, "\(fixtureName): Got \(baseBool), expected \(expectedBool)") - case(.date(let baseDate), .dictionary(let typeDictionary)): - guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], case .integer(let typeValue) = typeDictionary["value"] else { + case (.date(let baseDate), .dictionary(let typeDictionary)): + guard typeDictionary.count == 2, case .string(let typeName) = typeDictionary["__type"], + case .integer(let typeValue) = typeDictionary["value"] + else { XCTFail("\(fixtureName): Unexpected type dict \(typeDictionary)") return } @@ -73,12 +92,20 @@ final class StructuredFieldParserTests: XCTestCase { } } - private func _validateParameters(_ parameters: OrderedMap, against schema: JSONSchema, fixtureName: String) throws { + private func _validateParameters( + _ parameters: OrderedMap, + against schema: JSONSchema, + fixtureName: String + ) throws { guard case .dictionary(let expectedParameters) = schema else { XCTFail("\(fixtureName): Expected parameters to be a JSON dictionary, but got \(schema)") return } - XCTAssertEqual(expectedParameters.count, parameters.count, "\(fixtureName): Different numbers of parameters: expected \(expectedParameters), got \(parameters)") + XCTAssertEqual( + expectedParameters.count, + parameters.count, + "\(fixtureName): Different numbers of parameters: expected \(expectedParameters), got \(parameters)" + ) for (name, value) in parameters { guard let expectedValue = expectedParameters[name] else { XCTFail("\(fixtureName): Did not contain parameter for \(name)") @@ -106,12 +133,17 @@ final class StructuredFieldParserTests: XCTestCase { guard case .array(let arrayElements) = schema, arrayElements.count == 2, case .some(.array(let expectedItems)) = arrayElements.first, - let expectedParameters = arrayElements.last else { + let expectedParameters = arrayElements.last + else { XCTFail("\(fixtureName): Unexpected inner list: got \(innerList), expected \(schema)") return } - XCTAssertEqual(expectedItems.count, innerList.bareInnerList.count, "\(fixtureName): Unexpected inner list items: expected \(expectedItems), got \(innerList.bareInnerList)") + XCTAssertEqual( + expectedItems.count, + innerList.bareInnerList.count, + "\(fixtureName): Unexpected inner list items: expected \(expectedItems), got \(innerList.bareInnerList)" + ) for (actualItem, expectedItem) in zip(innerList.bareInnerList, expectedItems) { try self._validateItem(actualItem, against: expectedItem, fixtureName: fixtureName) } @@ -125,7 +157,11 @@ final class StructuredFieldParserTests: XCTestCase { return } - XCTAssertEqual(arrayElements.count, result.count, "\(fixtureName): Different counts in list: got \(result), expected \(arrayElements)") + XCTAssertEqual( + arrayElements.count, + result.count, + "\(fixtureName): Different counts in list: got \(result), expected \(arrayElements)" + ) for (innerResult, expectedElement) in zip(result, arrayElements) { switch innerResult { case .innerList(let innerList): @@ -136,13 +172,21 @@ final class StructuredFieldParserTests: XCTestCase { } } - private func _validateDictionary(_ result: OrderedMap, against schema: JSONSchema, fixtureName: String) throws { + private func _validateDictionary( + _ result: OrderedMap, + against schema: JSONSchema, + fixtureName: String + ) throws { guard case .dictionary(let expectedElements) = schema else { XCTFail("\(fixtureName): Unexpected dictionary: got \(result), expected \(schema)") return } - XCTAssertEqual(expectedElements.count, result.count, "\(fixtureName): Different counts in dictionary: got \(result), expected \(expectedElements)") + XCTAssertEqual( + expectedElements.count, + result.count, + "\(fixtureName): Different counts in dictionary: got \(result), expected \(expectedElements)" + ) for (key, value) in result { guard let expectedEntry = expectedElements[key] else { XCTFail("\(fixtureName): Could not find \(key) in \(expectedElements)") diff --git a/Tests/StructuredFieldValuesTests/StructuredFieldSerializerTests.swift b/Tests/StructuredFieldValuesTests/StructuredFieldSerializerTests.swift index c28bdf5..768a9f8 100644 --- a/Tests/StructuredFieldValuesTests/StructuredFieldSerializerTests.swift +++ b/Tests/StructuredFieldValuesTests/StructuredFieldSerializerTests.swift @@ -52,12 +52,17 @@ final class StructuredFieldSerializerTests: XCTestCase { XCTFail("\(fixture.name): Fixture did not throw when serializing.") } else if let canonical = fixture.canonical { let expectedCanonicalForm = canonical.joined(separator: ", ") - XCTAssertEqual(Array(expectedCanonicalForm.utf8), result, - "\(fixture.name): Bad serialization, expected \(expectedCanonicalForm), got \(String(decoding: result, as: UTF8.self))") + XCTAssertEqual( + Array(expectedCanonicalForm.utf8), + result, + "\(fixture.name): Bad serialization, expected \(expectedCanonicalForm), got \(String(decoding: result, as: UTF8.self))" + ) } } catch { - XCTAssert(fixture.mustFail == true || fixture.canFail == true, - "\(fixture.name): Unexpected failure, threw error \(error)") + XCTAssert( + fixture.mustFail == true || fixture.canFail == true, + "\(fixture.name): Unexpected failure, threw error \(error)" + ) } } @@ -103,7 +108,11 @@ final class StructuredFieldSerializerTests: XCTestCase { serialized = try serializer.writeItemFieldValue(item) } - XCTAssertEqual(canonicalJoinedHeaders, serialized, "\(fixture.name): Header serialization mismatch: expected \(String(decoding: canonicalJoinedHeaders, as: UTF8.self)), got \(String(decoding: serialized, as: UTF8.self))") + XCTAssertEqual( + canonicalJoinedHeaders, + serialized, + "\(fixture.name): Header serialization mismatch: expected \(String(decoding: canonicalJoinedHeaders, as: UTF8.self)), got \(String(decoding: serialized, as: UTF8.self))" + ) } catch { XCTFail("\(fixture.name): Fixture threw unexpected error \(error)") } @@ -142,7 +151,9 @@ extension StructuredFieldSerializerTests.TestResult { case .array(let jsonArray): // Top level JSON arrays may be either list headers or item headers. To know, we have // to investigate a bit. An item will have only two entries, and neither will be an array. - if jsonArray.count == 2, let first = jsonArray.first, let last = jsonArray.last, !first.isArray, !last.isArray { + if jsonArray.count == 2, let first = jsonArray.first, let last = jsonArray.last, !first.isArray, + !last.isArray + { // This is an item! self = .item(try Item(schema)) } else { @@ -172,7 +183,9 @@ extension ItemOrInnerList { extension Item { init(_ schema: JSONSchema) throws { - guard case .array(let arrayElements) = schema, arrayElements.count == 2, let first = arrayElements.first, let last = arrayElements.last else { + guard case .array(let arrayElements) = schema, arrayElements.count == 2, let first = arrayElements.first, + let last = arrayElements.last + else { fatalError("Invalid item: \(schema)") } @@ -214,7 +227,9 @@ extension RFC9651BareItem { extension InnerList { init(_ schema: JSONSchema) throws { - guard case .array(let arrayElements) = schema, arrayElements.count == 2, let first = arrayElements.first, let last = arrayElements.last else { + guard case .array(let arrayElements) = schema, arrayElements.count == 2, let first = arrayElements.first, + let last = arrayElements.last + else { fatalError("Invalid item: \(schema)") } diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 2bdd403..0000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -ARG swift_version=5.7 -ARG ubuntu_version=focal -ARG base_image=swift:$swift_version-$ubuntu_version -FROM $base_image -# needed to do again after FROM due to docker limitation -ARG swift_version -ARG ubuntu_version - -# set as UTF-8 -RUN apt-get update && apt-get install -y locales locales-all -ENV LC_ALL en_US.UTF-8 -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US.UTF-8 - -# dependencies -RUN apt-get update && apt-get install -y wget -RUN apt-get update && apt-get install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests - -# ruby and jazzy for docs generation, only on focal -RUN apt-get update && apt-get install -y ruby ruby-dev libsqlite3-dev build-essential -RUN if [ "${ubuntu_version}" = "focal" ] ; then echo "gem: --no-document" > ~/.gemrc; fi -RUN if [ "${ubuntu_version}" == "focal" ] ; then gem install jazzy; fi - -# tools -RUN mkdir -p $HOME/.tools -RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile - -# swiftformat (until part of the toolchain) - -ARG swiftformat_version=0.40.12 -RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format -RUN cd $HOME/.tools/swift-format && swift build -c release -RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat diff --git a/docker/docker-compose.2204.510.yaml b/docker/docker-compose.2204.510.yaml deleted file mode 100644 index 0186482..0000000 --- a/docker/docker-compose.2204.510.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-http-structured-headers:22.04-5.10 - build: - args: - ubuntu_version: "jammy" - swift_version: "5.10" - - unit-tests: - image: swift-http-structured-headers:22.04-5.10 - - documentation-check: - image: swift-http-structured-headers:22.04-5.10 - - test: - image: swift-http-structured-headers:22.04-5.10 - environment: - - IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error - - shell: - image: swift-http-structured-headers:22.04-5.10 - diff --git a/docker/docker-compose.2204.58.yaml b/docker/docker-compose.2204.58.yaml deleted file mode 100644 index 263b104..0000000 --- a/docker/docker-compose.2204.58.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-http-structured-headers:22.04-5.8 - build: - args: - ubuntu_version: "jammy" - swift_version: "5.8" - - unit-tests: - image: swift-http-structured-headers:22.04-5.8 - - documentation-check: - image: swift-http-structured-headers:22.04-5.8 - - test: - image: swift-http-structured-headers:22.04-5.8 - environment: - - IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error - - shell: - image: swift-http-structured-headers:22.04-5.8 - diff --git a/docker/docker-compose.2204.59.yaml b/docker/docker-compose.2204.59.yaml deleted file mode 100644 index 7bdf698..0000000 --- a/docker/docker-compose.2204.59.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-http-structured-headers:22.04-5.9 - build: - args: - ubuntu_version: "jammy" - swift_version: "5.9" - - unit-tests: - image: swift-http-structured-headers:22.04-5.9 - - documentation-check: - image: swift-http-structured-headers:22.04-5.9 - - test: - image: swift-http-structured-headers:22.04-5.9 - environment: - - IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error - - shell: - image: swift-http-structured-headers:22.04-5.9 - diff --git a/docker/docker-compose.2204.main.yaml b/docker/docker-compose.2204.main.yaml deleted file mode 100644 index 2212dfa..0000000 --- a/docker/docker-compose.2204.main.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-http-structured-headers:22.04-main - build: - args: - base_image: "swiftlang/swift:nightly-main-jammy" - ubuntu_version: "jammy" - - unit-tests: - image: swift-http-structured-headers:22.04-main - - documentation-check: - image: swift-http-structured-headers:22.04-main - - test: - image: swift-http-structured-headers:22.04-main - environment: - - IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error - - shell: - image: swift-http-structured-headers:22.04-main - diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml deleted file mode 100644 index 1c62227..0000000 --- a/docker/docker-compose.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# this file is not designed to be run directly -# instead, use the docker-compose.. files -# eg docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.1604.41.yaml run test -version: "3" - -services: - - runtime-setup: - image: swift-http-structured-headers:default - build: - context: . - dockerfile: Dockerfile - - common: &common - image: swift-http-structured-headers:default - depends_on: [runtime-setup] - volumes: - - ~/.ssh:/root/.ssh - - ..:/code:z - working_dir: /code - cap_drop: - - CAP_NET_RAW - - CAP_NET_BIND_SERVICE - - soundness: - <<: *common - command: /bin/bash -xcl "./scripts/soundness.sh" - - unit-tests: - <<: *common - command: /bin/bash -xcl "swift test --enable-test-discovery -Xswiftc -warnings-as-errors" - - documentation-check: - <<: *common - command: /bin/bash -xcl "./scripts/check-docs.sh" - - test: - <<: *common - command: /bin/bash -xcl "swift test --enable-test-discovery -Xswiftc -warnings-as-errors $${SANITIZER_ARG-} $${IMPORT_CHECK_ARG-}" - - - # util - - shell: - <<: *common - entrypoint: /bin/bash diff --git a/scripts/check-docs.sh b/scripts/check-docs.sh deleted file mode 100755 index 9405b7e..0000000 --- a/scripts/check-docs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2023 Apple Inc. and the SwiftNIO project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftNIO project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## - -set -eu - -raw_targets=$(sed -E -n -e 's/^.* - documentation_targets: \[(.*)\].*$/\1/p' .spi.yml) -targets=(${raw_targets//,/ }) - -for target in "${targets[@]}"; do - swift package plugin generate-documentation --target "$target" --warnings-as-errors --analyze --level detailed -done diff --git a/scripts/check_no_api_breakages.sh b/scripts/check_no_api_breakages.sh deleted file mode 100755 index f5ba64d..0000000 --- a/scripts/check_no_api_breakages.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftNIO project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## - -set -eu - -# repodir -function all_modules() { - local repodir="$1" - ( - set -eu - cd "$repodir" - swift package dump-package | jq '.products | - map(select(.type | has("library") )) | - map(.name) | .[]' | tr -d '"' - ) -} - -# repodir tag output -function build_and_do() { - local repodir=$1 - local tag=$2 - local output=$3 - - ( - cd "$repodir" - git checkout -q "$tag" - swift build - while read -r module; do - swift api-digester -sdk "$sdk" -dump-sdk -module "$module" \ - -o "$output/$module.json" -I "$repodir/.build/debug" - done < <(all_modules "$repodir") - ) -} - -function usage() { - echo >&2 "Usage: $0 REPO-GITHUB-URL NEW-VERSION OLD-VERSIONS..." - echo >&2 - echo >&2 "This script requires a Swift 5.1+ toolchain." - echo >&2 - echo >&2 "Examples:" - echo >&2 - echo >&2 "Check between main and tag 2.1.1 of swift-http-structured-headers:" - echo >&2 " $0 https://github.com/apple/swift-http-structured-headers main 2.1.1" - echo >&2 - echo >&2 "Check between HEAD and commit 64cf63d7 using the provided toolchain:" - echo >&2 " xcrun --toolchain org.swift.5120190702a $0 ../some-local-repo HEAD 64cf63d7" -} - -if [[ $# -lt 3 ]]; then - usage - exit 1 -fi - -sdk=/ -if [[ "$(uname -s)" == Darwin ]]; then - sdk=$(xcrun --show-sdk-path) -fi - -hash jq 2> /dev/null || { echo >&2 "ERROR: jq must be installed"; exit 1; } -tmpdir=$(mktemp -d /tmp/.check-api_XXXXXX) -repo_url=$1 -new_tag=$2 -shift 2 - -repodir="$tmpdir/repo" -git clone "$repo_url" "$repodir" -git -C "$repodir" fetch -q origin '+refs/pull/*:refs/remotes/origin/pr/*' -errors=0 - -for old_tag in "$@"; do - mkdir "$tmpdir/api-old" - mkdir "$tmpdir/api-new" - - echo "Checking public API breakages from $old_tag to $new_tag" - - build_and_do "$repodir" "$new_tag" "$tmpdir/api-new/" - build_and_do "$repodir" "$old_tag" "$tmpdir/api-old/" - - for f in "$tmpdir/api-new"/*; do - f=$(basename "$f") - report="$tmpdir/$f.report" - if [[ ! -f "$tmpdir/api-old/$f" ]]; then - echo "NOTICE: NEW MODULE $f" - continue - fi - - echo -n "Checking $f... " - swift api-digester -sdk "$sdk" -diagnose-sdk \ - --input-paths "$tmpdir/api-old/$f" -input-paths "$tmpdir/api-new/$f" 2>&1 \ - > "$report" 2>&1 - - if ! shasum "$report" | grep -q cefc4ee5bb7bcdb7cb5a7747efa178dab3c794d5; then - echo ERROR - echo >&2 "==============================" - echo >&2 "ERROR: public API change in $f" - echo >&2 "==============================" - cat >&2 "$report" - errors=$(( errors + 1 )) - else - echo OK - fi - done - rm -rf "$tmpdir/api-new" "$tmpdir/api-old" -done - -if [[ "$errors" == 0 ]]; then - echo "OK, all seems good" -fi -echo done -exit "$errors" diff --git a/scripts/generate_docs.sh b/scripts/generate_docs.sh deleted file mode 100755 index e7f9a0a..0000000 --- a/scripts/generate_docs.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftNIO project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## - -set -e - -my_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -root_path="$my_path/.." -version=$(git describe --abbrev=0 --tags || echo "0.0.0") -modules=(Crypto) - -if [[ "$(uname -s)" == "Linux" ]]; then - # build code if required - if [[ ! -d "$root_path/.build/x86_64-unknown-linux" ]]; then - swift build - fi - # setup source-kitten if required - mkdir -p "$root_path/.build/sourcekitten" - source_kitten_source_path="$root_path/.build/sourcekitten/source" - if [[ ! -d "$source_kitten_source_path" ]]; then - git clone https://github.com/jpsim/SourceKitten.git "$source_kitten_source_path" - fi - source_kitten_path="$source_kitten_source_path/.build/x86_64-unknown-linux/debug" - if [[ ! -d "$source_kitten_path" ]]; then - rm -rf "$source_kitten_source_path/.swift-version" - cd "$source_kitten_source_path" && swift build && cd "$root_path" - fi - # generate - for module in "${modules[@]}"; do - if [[ ! -f "$root_path/.build/sourcekitten/$module.json" ]]; then - "$source_kitten_path/sourcekitten" doc --module-name $module > "$root_path/.build/sourcekitten/$module.json" - fi - done -fi - -jazzy_dir="$root_path/.build/jazzy" -rm -rf "$jazzy_dir" -mkdir -p "$jazzy_dir" - -# prep index -module_switcher="$jazzy_dir/README.md" -cat > "$module_switcher" <<"EOF" -# swift-http-structured-headers Docs - -swift-http-structured-headers is a Swift package. - -To get started with swift-http-structured-headers, [`import CodableStructuredHeaders`](../CodableStructuredHeaders/index.html). -EOF - -# run jazzy -if ! command -v jazzy > /dev/null; then - gem install jazzy --no-ri --no-rdoc -fi - -jazzy_args=(--clean - --author 'SwiftNIO team' - --readme "$module_switcher" - --author_url https://github.com/apple/swift-http-structured-headers - --github_url https://github.com/apple/swift-http-structured-headers - --github-file-prefix https://github.com/apple/swift-http-structured-headers/tree/$version - --theme fullwidth - --swift-build-tool spm) - -for module in "${modules[@]}"; do - args=("${jazzy_args[@]}" --output "$jazzy_dir/docs/$version/$module" --docset-path "$jazzy_dir/docset/$version/$module" - --module "$module" --module-version $version - --root-url "https://apple.github.io/swift-http-structured-headers/docs/$version/$module/") - if [[ "$(uname -s)" == "Linux" ]]; then - args+=(--sourcekitten-sourcefile "$root_path/.build/sourcekitten/$module.json") - fi - jazzy "${args[@]}" -done - -# push to github pages -if [[ $PUSH == true ]]; then - BRANCH_NAME=$(git rev-parse --abbrev-ref HEAD) - GIT_AUTHOR=$(git --no-pager show -s --format='%an <%ae>' HEAD) - git fetch origin +gh-pages:gh-pages - git checkout gh-pages - rm -rf "docs/$version" - rm -rf "docs/current" - cp -r "$jazzy_dir/docs/$version" docs/ - cp -r "docs/$version" docs/current - git add --all docs - echo '' > index.html - git add index.html - touch .nojekyll - git add .nojekyll - changes=$(git diff-index --name-only HEAD) - if [[ -n "$changes" ]]; then - echo -e "changes detected\n$changes" - git commit --author="$GIT_AUTHOR" -m "publish $version docs" - git push origin gh-pages - else - echo "no changes detected" - fi - git checkout -f $BRANCH_NAME -fi diff --git a/scripts/soundness.sh b/scripts/soundness.sh deleted file mode 100755 index 6c0aad2..0000000 --- a/scripts/soundness.sh +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) 2020-2022 Apple Inc. and the SwiftNIO project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftNIO project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## - -set -eu -here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -function replace_acceptable_years() { - # this needs to replace all acceptable forms with 'YEARS' - sed -e 's/202[0123]-202[0123]/YEARS/' -e 's/202[0123]/YEARS/' -} - - -printf "=> Checking format... " -FIRST_OUT="$(git status --porcelain)" -swiftformat . > /dev/null 2>&1 -SECOND_OUT="$(git status --porcelain)" -if [[ "$FIRST_OUT" != "$SECOND_OUT" ]]; then - printf "\033[0;31mformatting issues!\033[0m\n" - git --no-pager diff - exit 1 -else - printf "\033[0;32mokay.\033[0m\n" -fi - -printf "=> Checking for unacceptable language... " -# This greps for unacceptable terminology. The square bracket[s] are so that -# "git grep" doesn't find the lines that greps :). -unacceptable_terms=( - -e blacklis[t] - -e whitelis[t] - -e slav[e] - -e sanit[y] -) -if git grep --color=never -i "${unacceptable_terms[@]}" > /dev/null; then - printf "\033[0;31mUnacceptable language found.\033[0m\n" - git grep -i "${unacceptable_terms[@]}" - exit 1 -fi -printf "\033[0;32mokay.\033[0m\n" - -printf "=> Checking license headers\n" -tmp=$(mktemp /tmp/.swift-http-structured-headers-soundness_XXXXXX) - -for language in swift-or-c bash dtrace; do - printf " * $language... " - declare -a matching_files - declare -a exceptions - expections=( ) - matching_files=( -name '*' ) - case "$language" in - swift-or-c) - exceptions=( -name 'Package.swift' -o -name 'Package@swift*.swift' ) - matching_files=( -name '*.swift' -o -name '*.c' -o -name '*.h' ) - cat > "$tmp" <<"EOF" -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftNIO open source project -// -// Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftNIO project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -EOF - ;; - bash) - matching_files=( -name '*.sh' ) - cat > "$tmp" <<"EOF" -#!/bin/bash -##===----------------------------------------------------------------------===## -## -## This source file is part of the SwiftNIO open source project -## -## Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors -## Licensed under Apache License v2.0 -## -## See LICENSE.txt for license information -## See CONTRIBUTORS.txt for the list of SwiftNIO project authors -## -## SPDX-License-Identifier: Apache-2.0 -## -##===----------------------------------------------------------------------===## -EOF - ;; - dtrace) - matching_files=( -name '*.d' ) - cat > "$tmp" <<"EOF" -#!/usr/sbin/dtrace -q -s -/*===----------------------------------------------------------------------===* - * - * This source file is part of the SwiftNIO open source project - * - * Copyright (c) YEARS Apple Inc. and the SwiftNIO project authors - * Licensed under Apache License v2.0 - * - * See LICENSE.txt for license information - * See CONTRIBUTORS.txt for the list of SwiftNIO project authors - * - * SPDX-License-Identifier: Apache-2.0 - * - *===----------------------------------------------------------------------===*/ -EOF - ;; - *) - echo >&2 "ERROR: unknown language '$language'" - ;; - esac - - expected_lines=$(cat "$tmp" | wc -l) - expected_sha=$(cat "$tmp" | shasum) - - ( - cd "$here/.." - find . \ - \( \! -path './.build/*' -a \ - \( "${matching_files[@]}" \) -a \ - \( \! \( "${exceptions[@]}" \) \) \) | while read line; do - if [[ "$(cat "$line" | replace_acceptable_years | head -n $expected_lines | shasum)" != "$expected_sha" ]]; then - printf "\033[0;31mmissing headers in file '$line'!\033[0m\n" - diff -u <(cat "$line" | replace_acceptable_years | head -n $expected_lines) "$tmp" - exit 1 - fi - done - printf "\033[0;32mokay.\033[0m\n" - ) -done - -rm "$tmp" From 59c3fdf953d5870712793c779b93d19ef635ad96 Mon Sep 17 00:00:00 2001 From: Rick Newton-Rogers Date: Tue, 29 Oct 2024 10:53:33 +0000 Subject: [PATCH 2/2] fix protocol warnings --- .../Decoder/BareItemDecoder.swift | 12 ++++++++++++ .../Encoder/StructuredFieldValueEncoder.swift | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift b/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift index d287a0e..4503d40 100644 --- a/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/BareItemDecoder.swift @@ -62,6 +62,18 @@ extension BareItemDecoder: SingleValueDecodingContainer { try self._decodeFixedWidthInteger(type) } + #if compiler(>=6.0) + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + func decode(_ type: UInt128.Type) throws -> UInt128 { + try self._decodeFixedWidthInteger(type) + } + + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + func decode(_ type: Int128.Type) throws -> Int128 { + try self._decodeFixedWidthInteger(type) + } + #endif + func decode(_ type: UInt.Type) throws -> UInt { try self._decodeFixedWidthInteger(type) } diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift index 1ffe2f1..e34b168 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift @@ -260,6 +260,13 @@ extension _StructuredFieldEncoder: SingleValueEncodingContainer { try self._encodeFixedWidthInteger(value) } + #if compiler(>=6.0) + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + func encode(_ value: Int128) throws { + try self._encodeFixedWidthInteger(value) + } + #endif + func encode(_ value: UInt) throws { try self._encodeFixedWidthInteger(value) } @@ -280,6 +287,13 @@ extension _StructuredFieldEncoder: SingleValueEncodingContainer { try self._encodeFixedWidthInteger(value) } + #if compiler(>=6.0) + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + func encode(_ value: UInt128) throws { + try self._encodeFixedWidthInteger(value) + } + #endif + func encode(_ data: Data) throws { let encoded = data.base64EncodedString() try self.currentStackEntry.storage.insertBareItem(.undecodedByteSequence(encoded))