diff --git a/Sources/Testing/ABI/Encoded/ABI.EncodedAttachment.swift b/Sources/Testing/ABI/Encoded/ABI.EncodedAttachment.swift index 013e129f6..649cd69b2 100644 --- a/Sources/Testing/ABI/Encoded/ABI.EncodedAttachment.swift +++ b/Sources/Testing/ABI/Encoded/ABI.EncodedAttachment.swift @@ -103,10 +103,6 @@ extension ABI.EncodedAttachment: Attachable { _bytes?.rawValue.count } - /// An error type that is thrown when ``ABI/EncodedAttachment`` cannot satisfy - /// a request for the underlying attachment's bytes. - fileprivate struct BytesUnavailableError: Error {} - borrowing func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { if let bytes = _bytes?.rawValue { return try bytes.withUnsafeBytes(body) @@ -135,9 +131,3 @@ extension ABI.EncodedAttachment: Attachable { _preferredName ?? suggestedName } } - -extension ABI.EncodedAttachment.BytesUnavailableError: CustomStringConvertible { - var description: String { - "The attachment's content could not be deserialized." - } -} diff --git a/Sources/Testing/Attachments/Attachable.swift b/Sources/Testing/Attachments/Attachable.swift index 8c3476657..f9a196309 100644 --- a/Sources/Testing/Attachments/Attachable.swift +++ b/Sources/Testing/Attachments/Attachable.swift @@ -80,6 +80,9 @@ public protocol Attachable: ~Copyable { /// } borrowing func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R + @_lifetime(borrow self) + borrowing func bytes(for attachment: borrowing Attachment) throws -> RawSpan + /// Generate a preferred name for the given attachment. /// /// - Parameters: @@ -101,6 +104,18 @@ public protocol Attachable: ~Copyable { borrowing func preferredName(for attachment: borrowing Attachment, basedOn suggestedName: String) -> String } +// MARK: - + +/// An error type that is thrown when the testing library cannot satisfy a +/// request for an attachment's bytes. +struct BytesUnavailableError: Error {} + +extension BytesUnavailableError: CustomStringConvertible { + var description: String { + "The attachment's content could not be deserialized." + } +} + // MARK: - Default implementations /// @Metadata { @@ -123,6 +138,11 @@ extension Attachable where Self: ~Copyable { public borrowing func preferredName(for attachment: borrowing Attachment, basedOn suggestedName: String) -> String { suggestedName } + + @_lifetime(borrow self) + public borrowing func bytes(for attachment: borrowing Attachment) throws -> RawSpan { + throw BytesUnavailableError() + } } /// @Metadata { @@ -202,6 +222,11 @@ extension ContiguousArray: Attachable { public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } + + @_lifetime(borrow self) + public borrowing func bytes(for attachment: borrowing Attachment) throws -> RawSpan { + span.bytes + } } /// @Metadata { @@ -216,6 +241,11 @@ extension ArraySlice: Attachable { public func withUnsafeBytes(for attachment: borrowing Attachment, _ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try withUnsafeBytes(body) } + + @_lifetime(borrow self) + public borrowing func bytes(for attachment: borrowing Attachment) throws -> RawSpan { + span.bytes + } } /// @Metadata { diff --git a/Sources/Testing/Attachments/Attachment.swift b/Sources/Testing/Attachments/Attachment.swift index 5971df29e..8586b2c28 100644 --- a/Sources/Testing/Attachments/Attachment.swift +++ b/Sources/Testing/Attachments/Attachment.swift @@ -366,6 +366,20 @@ extension Attachment where AttachableValue: ~Copyable { @inlinable public borrowing func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) throws -> R { try attachableValue.withUnsafeBytes(for: self, body) } + + @_lifetime(borrow self) + private func _makeBytes(from attachableValue: borrowing AttachableValue) throws -> RawSpan { + let result = try attachableValue.bytes(for: self) + return _overrideLifetime(result, copying: self) + } + + @_spi(Experimental) + public var bytes: RawSpan { + @_lifetime(borrow self) + borrowing get throws { + try _makeBytes(from: _storage.value) + } + } } #if !SWT_NO_FILE_IO