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

Code before:
    #if compiler(>=6.2)
    /// Create a fresh ``ByteBuffer`` with a minimum size, and initializing it safely via an `OutputSpan`.
    ///
    /// This will allocate a new ``ByteBuffer`` with at least `capacity` bytes of storage, and then calls
    /// `initializer` with an `OutputSpan` over the entire allocated storage. This is a convenient method
    /// to initialize a buffer directly and safely in a single allocation, including from C code.
    ///
    /// Once this call returns, the buffer will have its ``ByteBuffer/writerIndex`` appropriately advanced to encompass
    /// any memory initialized by the `initializer`. Uninitialized memory will be after the ``ByteBuffer/writerIndex``,
    /// available for subsequent use.
    ///
    /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we
    ///         recommend using `channel.allocator.buffer(capacity:initializingWith:)`. Or if you want to write multiple items into
    ///         the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right
    ///         size followed by a `write(minimumWritableBytes:initializingWith:)` instead of using this method. This allows SwiftNIO to do
    ///         accounting and optimisations of resources acquired for operations on a given `Channel` in the future.
    ///
    /// - parameters:
    ///     - capacity: The minimum initial space to allocate for the buffer.
    ///     - initializer: The initializer that will be invoked to initialize the allocated memory.
    @inlinable
    @available(macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2, visionOS 1.0, *)
    public init(
        initialCapacity capacity: Int,
        initializingWith initializer: (_ span: inout OutputRawSpan) throws -> Void
    ) rethrows {
        self = try ByteBufferAllocator().buffer(capacity: capacity, initializingWith: initializer)
    }
    #endif
}

extension ByteBuffer: Codable {

    /// Creates a ByteByffer by decoding from a Base64 encoded single value container.
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let base64String = try container.decode(String.self)
        self = try ByteBuffer(bytes: base64String._base64Decoded())
    }

    /// Encodes this buffer as a base64 string in a single value container.
    public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        let base64String = String(_base64Encoding: self.readableBytesView)
        try container.encode(base64String)
    }
}

extension ByteBufferAllocator {
    /// Create a fresh `ByteBuffer` containing the bytes of the `string` encoded as UTF-8.
    ///

Review comment (suggestion):
Instead of using rethrows can we use typed-throws here which composes better. Similar to the [InlineArray init](https://github.com/swiftlang/swift/blob/0063c3c522d777a5d2e34a04e965cb43726cd207/stdlib/public/core/InlineArray.swift#L301)

Code after:
    ///
    /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we
    ///         recommend using `channel.allocator.buffer(repeating:count:)`. Or if you want to write multiple items
    ///         into the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right
    ///         size followed by a `writeRepeatingByte` instead of using this method. This allows SwiftNIO to do
    ///         accounting and optimisations of resources acquired for operations on a given `Channel` in the future.
    @inlinable
    public init(repeating byte: UInt8, count: Int) {
        self = ByteBufferAllocator().buffer(repeating: byte, count: count)
    }

    /// Create a fresh `ByteBuffer` containing the readable bytes of `buffer`.
    ///
    /// This may allocate a new `ByteBuffer` with enough space to fit `buffer` and potentially some extra space using
    /// the default allocator.
    ///
    /// - Note: Use this method only if you deliberately want to reallocate a potentially smaller `ByteBuffer` than the
    ///         one you already have. Given that `ByteBuffer` is a value type, defensive copies are not necessary. If
    ///         you have a `ByteBuffer` but would like the `readerIndex` to start at `0`, consider `readSlice` instead.
    ///
    /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we
    ///         recommend using `channel.allocator.buffer(buffer:)`. Or if you want to write multiple items into the
    ///         buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right
    ///         size followed by a `writeImmutableBuffer` instead of using this method. This allows SwiftNIO to do
    ///         accounting and optimisations of resources acquired for operations on a given `Channel` in the future.
    @inlinable
    public init(buffer: ByteBuffer) {
        self = ByteBufferAllocator().buffer(buffer: buffer)
    }

    #if canImport(Dispatch)
    /// Create a fresh `ByteBuffer` containing the bytes contained in the given `DispatchData`.
    ///
    /// This will allocate a new `ByteBuffer` with enough space to fit the bytes of the `DispatchData` and potentially
    /// some extra space using the default allocator.
    ///
    /// - info: If you have access to a `Channel`, `ChannelHandlerContext`, or `ByteBufferAllocator` we
    ///         recommend using `channel.allocator.buffer(dispatchData:)`. Or if you want to write multiple items into
    ///         the buffer use `channel.allocator.buffer(capacity: ...)` to allocate a `ByteBuffer` of the right
    ///         size followed by a `writeDispatchData` instead of using this method. This allows SwiftNIO to do
    ///         accounting and optimisations of resources acquired for operations on a given `Channel` in the future.
    @inlinable
    public init(dispatchData: DispatchData) {
        self = ByteBufferAllocator().buffer(dispatchData: dispatchData)
    }
    #endif

    #if compiler(>=6.2)
    /// Create a fresh ``ByteBuffer`` with a minimum size, and initializing it safely via an `OutputSpan`.
    ///
    /// This will allocate a new ``ByteBuffer`` with at least `capacity` bytes of storage, and then calls