Repository: apple/swift-nio
File: Sources/NIOCore/ByteBuffer-hex.swift (Swift)

Code before:
            if let maxBytes = maxBytes {
                return self.hexDumpPlain(maxBytes: maxBytes)
            } else {
                return self.hexDumpPlain()
            }

        case .compact(let maxBytes):
            if let maxBytes = maxBytes {
                return self.hexDumpCompact(maxBytes: maxBytes)
            } else {
                return self.hexDumpCompact()
            }

        case .detailed(let maxBytes):
            if let maxBytes = maxBytes {
                return self.hexDumpDetailed(maxBytes: maxBytes)
            } else {
                return self.hexdumpDetailed()
            }
        }
    }

    public struct HexDecodingError: Error {
        let kind: HexDecodingErrorKind

        public enum HexDecodingErrorKind {
            case invalidHexLength
            case invalidCharacter
        }
    }
}

extension UInt8 {
    fileprivate var isASCIIWhitespace: Bool {
        [UInt8(ascii: "\n"), UInt8(ascii: "\t"), UInt8(ascii: "\r"), UInt8(ascii: " ")].contains(
            self
        )
    }

    fileprivate var asciiHexNibble: UInt8 {
        get throws {
            switch self {
            case UInt8(ascii: "0")...UInt8(ascii: "9"):
                return self - UInt8(ascii: "0")
            case UInt8(ascii: "a")...UInt8(ascii: "f"):
                return self - UInt8(ascii: "a") + 10
            case UInt8(ascii: "A")...UInt8(ascii: "F"):
                return self - UInt8(ascii: "A") + 10
            default:
                throw ByteBuffer.HexDecodingError(kind: .invalidCharacter)
            }

Review comment (suggestion):
This `enum` needs to be private, or we can't safely use this type.

Code after:
            if let maxBytes = maxBytes {
                return self.hexDumpPlain(maxBytes: maxBytes)
            } else {
                return self.hexDumpPlain()
            }

        case .compact(let maxBytes):
            if let maxBytes = maxBytes {
                return self.hexDumpCompact(maxBytes: maxBytes)
            } else {
                return self.hexDumpCompact()
            }

        case .detailed(let maxBytes):
            if let maxBytes = maxBytes {
                return self.hexDumpDetailed(maxBytes: maxBytes)
            } else {
                return self.hexdumpDetailed()
            }
        }
    }

    /// An error that is thrown when an invalid hex encoded string was attempted to be written to a ByteBuffer.
    public struct HexDecodingError: Error, Equatable {
        private let kind: HexDecodingErrorKind

        private enum HexDecodingErrorKind {
            /// The hex encoded string was not of the expected even length.
            case invalidHexLength
            /// An invalid hex character was found in the hex encoded string.
            case invalidCharacter
        }

        public static let invalidHexLength = HexDecodingError(kind: .invalidHexLength)
        public static let invalidCharacter = HexDecodingError(kind: .invalidCharacter)
    }
}

extension UInt8 {
    fileprivate var isASCIIWhitespace: Bool {
        [UInt8(ascii: "\n"), UInt8(ascii: "\t"), UInt8(ascii: "\r"), UInt8(ascii: " ")].contains(
            self
        )
    }

    fileprivate var asciiHexNibble: UInt8 {
        get throws {
            switch self {
            case UInt8(ascii: "0")...UInt8(ascii: "9"):
                return self - UInt8(ascii: "0")
            case UInt8(ascii: "a")...UInt8(ascii: "f"):