Repository: vapor/vapor
File: Sources/Vapor/Content/PlaintextEncoder.swift (Swift)

Code before:
    
    public func encode<E>(_ encodable: E, to body: inout ByteBuffer, headers: inout HTTPHeaders, userInfo: [CodingUserInfoKey: Sendable]) throws
        where E: Encodable
    {
        let actualEncoder: _PlaintextEncoder
        if !userInfo.isEmpty {  // Changing a coder's userInfo is a thread-unsafe mutation, operate on a copy
            actualEncoder = _PlaintextEncoder(userInfo: self.encoder.userInfoSendable.merging(userInfo) { $1 })
        } else {
            actualEncoder = self.encoder
        }

        var container = actualEncoder.singleValueContainer()
        try container.encode(encodable)

        guard let string = actualEncoder.plaintext else {
            throw EncodingError.invalidValue(encodable, .init(codingPath: [], debugDescription: "Nothing was encoded!"))
        }
        headers.contentType = self.contentType
        body.writeString(string)
    }
}

// MARK: Private

private final class _PlaintextEncoder: Encoder, SingleValueEncodingContainer, @unchecked Sendable {
    public var codingPath: [CodingKey] = []
    fileprivate var userInfoSendable: [CodingUserInfoKey: Sendable]
    public var userInfo: [CodingUserInfoKey: Any] { self.userInfoSendable }
    public var plaintext: String?
    
    public init(userInfo: [CodingUserInfoKey: Sendable] = [:]) { self.userInfoSendable = userInfo }
    
    public func container<Key: CodingKey>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> { .init(FailureEncoder<Key>()) }
    public func unkeyedContainer() -> UnkeyedEncodingContainer { FailureEncoder() }
    public func singleValueContainer() -> SingleValueEncodingContainer { self }

    func encodeNil() throws { self.plaintext = nil }
    
    // N.B.: Implementing the individual "primitive" coding methods on a container rather than forwarding through
    // each type's Codable implementation yields substantial speedups.
    func encode(_ value: Bool) throws { self.plaintext = value.description }
    func encode(_ value: Int) throws { self.plaintext = value.description }
    func encode(_ value: Double) throws { self.plaintext = value.description }
    func encode(_ value: String) throws { self.plaintext = value }
    func encode(_ value: Int8) throws { self.plaintext = value.description }
    func encode(_ value: Int16) throws { self.plaintext = value.description }
    func encode(_ value: Int32) throws { self.plaintext = value.description }
    func encode(_ value: Int64) throws { self.plaintext = value.description }
    func encode(_ value: UInt) throws { self.plaintext = value.description }
    func encode(_ value: UInt8) throws { self.plaintext = value.description }
    func encode(_ value: UInt16) throws { self.plaintext = value.description }

Review comment (bug):
This is confusing - the properties shouldn't be public since it's a private type. Could we make these `(private) set` to avoid any potential data races?

Code after:
        let encoder = _PlaintextEncoder(userInfo: userInfo)
        var container = encoder.singleValueContainer()
        try container.encode(encodable)

        guard let string = encoder.plaintext else {
            throw EncodingError.invalidValue(encodable, .init(codingPath: [], debugDescription: "Nothing was encoded!"))
        }
        headers.contentType = self.contentType
        body.writeString(string)
    }
}

// MARK: Private

private final class _PlaintextEncoder: Encoder, SingleValueEncodingContainer {
    let codingPath: [CodingKey] = []
    let userInfoSendable: [CodingUserInfoKey: Sendable]
    var userInfo: [CodingUserInfoKey: Any] { self.userInfoSendable }
    private(set) var plaintext: String?

    init(userInfo: [CodingUserInfoKey: Sendable] = [:]) { self.userInfoSendable = userInfo }
    
    func container<Key: CodingKey>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> { .init(FailureEncoder<Key>()) }
    func unkeyedContainer() -> UnkeyedEncodingContainer { FailureEncoder() }
    func singleValueContainer() -> SingleValueEncodingContainer { self }

    func encodeNil() throws { self.plaintext = nil }
    
    // N.B.: Implementing the individual "primitive" coding methods on a container rather than forwarding through
    // each type's Codable implementation yields substantial speedups.
    func encode(_ value: Bool) throws { self.plaintext = value.description }
    func encode(_ value: Int) throws { self.plaintext = value.description }
    func encode(_ value: Double) throws { self.plaintext = value.description }
    func encode(_ value: String) throws { self.plaintext = value }
    func encode(_ value: Int8) throws { self.plaintext = value.description }
    func encode(_ value: Int16) throws { self.plaintext = value.description }
    func encode(_ value: Int32) throws { self.plaintext = value.description }
    func encode(_ value: Int64) throws { self.plaintext = value.description }
    func encode(_ value: UInt) throws { self.plaintext = value.description }
    func encode(_ value: UInt8) throws { self.plaintext = value.description }
    func encode(_ value: UInt16) throws { self.plaintext = value.description }
    func encode(_ value: UInt32) throws { self.plaintext = value.description }
    func encode(_ value: UInt64) throws { self.plaintext = value.description }
    func encode(_ value: Float) throws { self.plaintext = value.description }
    
    func encode<T>(_ value: T) throws where T: Encodable {
        if let data = value as? Data {
            // special case for data
#if swift(>=5.7.2)
            let utf8Maybe = data.withUnsafeBytes({ $0.withMemoryRebound(to: CChar.self, { String(validatingUTF8: $0.baseAddress!) }) })
#else