1616///
1717/// [W3C TraceContext: parent-id](https://www.w3.org/TR/trace-context-1/#parent-id)
1818public struct SpanID : Sendable {
19- private let _bytes : Bytes
20-
21- /// An 8-byte array representation of the span ID.
22- public var bytes : [ UInt8 ] {
23- withUnsafeBytes ( of: _bytes, Array . init)
24- }
19+ /// The 8 bytes making up the span ID.
20+ public let bytes : Bytes
2521
2622 /// Create a span ID from 8 bytes.
2723 ///
2824 /// - Parameter bytes: The 8 bytes making up the span ID.
2925 public init ( bytes: Bytes ) {
30- _bytes = bytes
26+ self . bytes = bytes
3127 }
3228
3329 /// Create a random span ID using the given random number generator.
3430 ///
3531 /// - Parameter randomNumberGenerator: The random number generator used to create random bytes for the span ID.
3632 /// - Returns: A random span ID.
3733 public static func random( using randomNumberGenerator: inout some RandomNumberGenerator ) -> SpanID {
38- var bytes : SpanID . Bytes = ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
39- withUnsafeMutableBytes ( of : & bytes) { ptr in
34+ var bytes : SpanID . Bytes = . null
35+ bytes. withUnsafeMutableBytes { ptr in
4036 ptr. storeBytes ( of: randomNumberGenerator. next ( ) . bigEndian, as: UInt64 . self)
4137 }
4238 return SpanID ( bytes: bytes)
@@ -49,68 +45,126 @@ public struct SpanID: Sendable {
4945 var generator = SystemRandomNumberGenerator ( )
5046 return random ( using: & generator)
5147 }
52-
53- /// An 8-byte array.
54- public typealias Bytes = ( UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 )
5548}
5649
57- extension SpanID : Equatable {
58- public static func == ( lhs: Self , rhs: Self ) -> Bool {
59- lhs. _bytes. 0 == rhs. _bytes. 0
60- && lhs. _bytes. 1 == rhs. _bytes. 1
61- && lhs. _bytes. 2 == rhs. _bytes. 2
62- && lhs. _bytes. 3 == rhs. _bytes. 3
63- && lhs. _bytes. 4 == rhs. _bytes. 4
64- && lhs. _bytes. 5 == rhs. _bytes. 5
65- && lhs. _bytes. 6 == rhs. _bytes. 6
66- && lhs. _bytes. 7 == rhs. _bytes. 7
67- }
68- }
50+ extension SpanID : Equatable { }
6951
70- extension SpanID : Hashable {
71- public func hash( into hasher: inout Hasher ) {
72- hasher. combine ( _bytes. 0 )
73- hasher. combine ( _bytes. 1 )
74- hasher. combine ( _bytes. 2 )
75- hasher. combine ( _bytes. 3 )
76- hasher. combine ( _bytes. 4 )
77- hasher. combine ( _bytes. 5 )
78- hasher. combine ( _bytes. 6 )
79- hasher. combine ( _bytes. 7 )
80- }
81- }
52+ extension SpanID : Hashable { }
8253
8354extension SpanID : Identifiable {
84- public var id : [ UInt8 ] { bytes }
55+ public var id : Self { self }
8556}
8657
8758extension SpanID : CustomStringConvertible {
8859 /// A 16 character hex string representation of the span ID.
60+ public var description : String {
61+ " \( bytes) "
62+ }
63+ }
64+
65+ // MARK: - Bytes
66+
67+ extension SpanID {
68+ /// An 8-byte array.
69+ public struct Bytes : Collection , Equatable , Hashable , Sendable {
70+ public static var null : Self { SpanID . Bytes ( ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) }
71+
72+ @usableFromInline
73+ var _bytes : ( UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 )
74+
75+ public init ( _ bytes: ( UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 , UInt8 ) ) {
76+ _bytes = bytes
77+ }
78+
79+ public subscript( position: Int ) -> UInt8 {
80+ switch position {
81+ case 0 : _bytes. 0
82+ case 1 : _bytes. 1
83+ case 2 : _bytes. 2
84+ case 3 : _bytes. 3
85+ case 4 : _bytes. 4
86+ case 5 : _bytes. 5
87+ case 6 : _bytes. 6
88+ case 7 : _bytes. 7
89+ default : fatalError ( " Index out of range " )
90+ }
91+ }
92+
93+ public func index( after i: Int ) -> Int {
94+ precondition ( i < endIndex, " Can't advance beyond endIndex " )
95+ return i + 1
96+ }
97+
98+ public var startIndex : Int { 0 }
99+ public var endIndex : Int { 8 }
100+
101+ @inlinable
102+ public func withContiguousStorageIfAvailable< Result> (
103+ _ body: ( UnsafeBufferPointer < UInt8 > ) throws -> Result
104+ ) rethrows -> Result ? {
105+ try Swift . withUnsafeBytes ( of: _bytes) { bytes in
106+ try bytes. withMemoryRebound ( to: UInt8 . self, body)
107+ }
108+ }
109+
110+ /// Calls the given closure with a pointer to the span ID's underlying bytes.
111+ ///
112+ /// - Parameter body: A closure receiving an `UnsafeRawBufferPointer` to the span ID's underlying bytes.
113+ @inlinable
114+ public func withUnsafeBytes< Result> ( _ body: ( UnsafeRawBufferPointer ) throws -> Result ) rethrows -> Result {
115+ try Swift . withUnsafeBytes ( of: _bytes, body)
116+ }
117+
118+ /// Calls the given closure with a mutable pointer to the span ID's underlying bytes.
119+ ///
120+ /// - Parameter body: A closure receiving an `UnsafeMutableRawBufferPointer` to the span ID's underlying bytes.
121+ @inlinable
122+ public mutating func withUnsafeMutableBytes< Result> (
123+ _ body: ( UnsafeMutableRawBufferPointer ) throws -> Result
124+ ) rethrows -> Result {
125+ try Swift . withUnsafeMutableBytes ( of: & _bytes) { bytes in
126+ try body ( bytes)
127+ }
128+ }
129+
130+ public static func == ( lhs: Self , rhs: Self ) -> Bool {
131+ lhs. _bytes. 0 == rhs. _bytes. 0
132+ && lhs. _bytes. 1 == rhs. _bytes. 1
133+ && lhs. _bytes. 2 == rhs. _bytes. 2
134+ && lhs. _bytes. 3 == rhs. _bytes. 3
135+ && lhs. _bytes. 4 == rhs. _bytes. 4
136+ && lhs. _bytes. 5 == rhs. _bytes. 5
137+ && lhs. _bytes. 6 == rhs. _bytes. 6
138+ && lhs. _bytes. 7 == rhs. _bytes. 7
139+ }
140+
141+ public func hash( into hasher: inout Hasher ) {
142+ hasher. combine ( _bytes. 0 )
143+ hasher. combine ( _bytes. 1 )
144+ hasher. combine ( _bytes. 2 )
145+ hasher. combine ( _bytes. 3 )
146+ hasher. combine ( _bytes. 4 )
147+ hasher. combine ( _bytes. 5 )
148+ hasher. combine ( _bytes. 6 )
149+ hasher. combine ( _bytes. 7 )
150+ }
151+ }
152+ }
153+
154+ extension SpanID . Bytes : CustomStringConvertible {
155+ /// A 16 character hex string representation of the bytes.
89156 public var description : String {
90157 String ( decoding: hexBytes, as: UTF8 . self)
91158 }
92159
93- /// A 16 character UTF-8 hex byte array representation of the span ID .
160+ /// A 16 character UTF-8 hex byte array representation of the bytes .
94161 public var hexBytes : [ UInt8 ] {
95- var asciiBytes : ( UInt64 , UInt64 ) = ( 0 , 0 )
96- return withUnsafeMutableBytes ( of: & asciiBytes) { ptr in
97- ptr [ 0 ] = Hex . lookup [ Int ( _bytes. 0 >> 4 ) ]
98- ptr [ 1 ] = Hex . lookup [ Int ( _bytes. 0 & 0x0F ) ]
99- ptr [ 2 ] = Hex . lookup [ Int ( _bytes. 1 >> 4 ) ]
100- ptr [ 3 ] = Hex . lookup [ Int ( _bytes. 1 & 0x0F ) ]
101- ptr [ 4 ] = Hex . lookup [ Int ( _bytes. 2 >> 4 ) ]
102- ptr [ 5 ] = Hex . lookup [ Int ( _bytes. 2 & 0x0F ) ]
103- ptr [ 6 ] = Hex . lookup [ Int ( _bytes. 3 >> 4 ) ]
104- ptr [ 7 ] = Hex . lookup [ Int ( _bytes. 3 & 0x0F ) ]
105- ptr [ 8 ] = Hex . lookup [ Int ( _bytes. 4 >> 4 ) ]
106- ptr [ 9 ] = Hex . lookup [ Int ( _bytes. 4 & 0x0F ) ]
107- ptr [ 10 ] = Hex . lookup [ Int ( _bytes. 5 >> 4 ) ]
108- ptr [ 11 ] = Hex . lookup [ Int ( _bytes. 5 & 0x0F ) ]
109- ptr [ 12 ] = Hex . lookup [ Int ( _bytes. 6 >> 4 ) ]
110- ptr [ 13 ] = Hex . lookup [ Int ( _bytes. 6 & 0x0F ) ]
111- ptr [ 14 ] = Hex . lookup [ Int ( _bytes. 7 >> 4 ) ]
112- ptr [ 15 ] = Hex . lookup [ Int ( _bytes. 7 & 0x0F ) ]
113- return Array ( ptr)
162+ var asciiBytes = [ UInt8] ( repeating: 0 , count: 16 )
163+ for i in startIndex ..< endIndex {
164+ let byte = self [ i]
165+ asciiBytes [ 2 * i] = Hex . lookup [ Int ( byte >> 4 ) ]
166+ asciiBytes [ 2 * i + 1 ] = Hex . lookup [ Int ( byte & 0x0F ) ]
114167 }
168+ return asciiBytes
115169 }
116170}
0 commit comments