Repository: vapor/vapor
File: Sources/Vapor/Utilities/URI.swift (Swift)

Code before:
    public var port: Int? {
        get { self.components?.port }
        set { self.components?.port = newValue }
    }

    public var path: String {
        get { self.components?.percentEncodedPath.replacingOccurrences(of: "%3B", with: ";", options: .literal) ?? "/" }
        set { self.components?.percentEncodedPath = newValue.withAllowedUrlDelimitersEncoded }
    }

    public var query: String? {
        get { self.components?.percentEncodedQuery }
        set { self.components?.percentEncodedQuery = newValue?.withAllowedUrlDelimitersEncoded }
    }

    public var fragment: String? {
        get { self.components?.percentEncodedFragment }
        set { self.components?.percentEncodedFragment = newValue?.withAllowedUrlDelimitersEncoded }
    }

    public var string: String {
        if urlPathAllowedIsBroken {
            // On Linux and in older Xcode versions, URLComponents incorrectly treats `;` as *not* allowed in the path component.
            let modify = self.components?.string ?? ""
            let replaceUntil = modify.firstIndex(where: { $0 == "?" || $0 == "#" }) ?? modify.endIndex
            return modify[modify.startIndex..<replaceUntil].replacingOccurrences(of: "%3B", with: ";") + modify[replaceUntil..<modify.endIndex]
        } else {
            return self.components?.string ?? ""
        }
    }
    
    // See `ExpressibleByStringInterpolation.init(stringLiteral:)`.
    public init(stringLiteral value: String) {
        self.init(string: value)
    }

    // See `CustomStringConvertible.description`.
    public var description: String {
        self.string
    }
}

// MARK: - URI.Scheme

extension URI {
    /// A URI scheme, as defined by [RFC 3986 § 3.1] and [RFC 7595].
    ///
    /// [RFC 3986 § 3.1]: https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
    /// [RGC 7595]: https://datatracker.ietf.org/doc/html/rfc7595
    public struct Scheme: CustomStringConvertible, ExpressibleByStringInterpolation, Hashable, Codable, Sendable {
        /// The string representation of the scheme.

Review comment (suggestion):
```suggestion
            let string = self.components?.string ?? ""
            return string.replacingOccurrences(
                of: "%3B", with: ";",
                options: .literal, // N.B.: `rangeOfPath` never actually returns `nil`
                range: self.components?.rangeOfPath ?? (string.startIndex..<string.startIndex)
            )
```

Code after:
    public var port: Int? {
        get { self.components?.port }
        set { self.components?.port = newValue }
    }

    public var path: String {
        get { self.components?.percentEncodedPath.replacingOccurrences(of: "%3B", with: ";", options: .literal) ?? "/" }
        set { self.components?.percentEncodedPath = newValue.withAllowedUrlDelimitersEncoded }
    }

    public var query: String? {
        get { self.components?.percentEncodedQuery }
        set { self.components?.percentEncodedQuery = newValue?.withAllowedUrlDelimitersEncoded }
    }

    public var fragment: String? {
        get { self.components?.percentEncodedFragment }
        set { self.components?.percentEncodedFragment = newValue?.withAllowedUrlDelimitersEncoded }
    }

    public var string: String {
        if urlPathAllowedIsBroken {
            // On Linux and in older Xcode versions, URLComponents incorrectly treats `;` as *not* allowed in the path component.
            let string = self.components?.string ?? ""
            return string.replacingOccurrences(
                of: "%3B", with: ";",
                options: .literal, // N.B.: `rangeOfPath` never actually returns `nil`
                range: self.components?.rangeOfPath ?? (string.startIndex..<string.startIndex)
            )
        } else {
            return self.components?.string ?? ""
        }
    }
    
    // See `ExpressibleByStringInterpolation.init(stringLiteral:)`.
    public init(stringLiteral value: String) {
        self.init(string: value)
    }

    // See `CustomStringConvertible.description`.
    public var description: String {
        self.string
    }
}

// MARK: - URI.Scheme

extension URI {
    /// A URI scheme, as defined by [RFC 3986 § 3.1] and [RFC 7595].
    ///
    /// [RFC 3986 § 3.1]: https://datatracker.ietf.org/doc/html/rfc3986#section-3.1