@@ -148,6 +148,34 @@ impl hash::Hash for OtelString {
148148 self . as_str ( ) . hash ( state)
149149 }
150150}
151+ #[ derive( Clone , Debug , Eq ) ]
152+ enum OtelBytes {
153+ Owned ( Vec < u8 > ) ,
154+ Static ( & ' static [ u8 ] ) ,
155+ RefCounted ( Arc < [ u8 ] > ) ,
156+ }
157+
158+ impl OtelBytes {
159+ fn as_slice ( & self ) -> & [ u8 ] {
160+ match self {
161+ OtelBytes :: Owned ( b) => b. as_ref ( ) ,
162+ OtelBytes :: Static ( b) => b,
163+ OtelBytes :: RefCounted ( b) => b. as_ref ( ) ,
164+ }
165+ }
166+ }
167+
168+ impl PartialEq for OtelBytes {
169+ fn eq ( & self , other : & Self ) -> bool {
170+ self . as_slice ( ) . eq ( other. as_slice ( ) )
171+ }
172+ }
173+
174+ impl hash:: Hash for OtelBytes {
175+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
176+ self . as_slice ( ) . hash ( state)
177+ }
178+ }
151179
152180/// A [Value::Array] containing homogeneous values.
153181#[ non_exhaustive]
@@ -161,6 +189,8 @@ pub enum Array {
161189 F64 ( Vec < f64 > ) ,
162190 /// Array of strings
163191 String ( Vec < StringValue > ) ,
192+ /// Array of bytes
193+ Bytes ( Vec < BytesValue > ) ,
164194}
165195
166196impl fmt:: Display for Array {
@@ -179,6 +209,16 @@ impl fmt::Display for Array {
179209 }
180210 write ! ( fmt, "]" )
181211 }
212+ Array :: Bytes ( values) => {
213+ write ! ( fmt, "[" ) ?;
214+ for ( i, b) in values. iter ( ) . enumerate ( ) {
215+ if i > 0 {
216+ write ! ( fmt, "," ) ?;
217+ }
218+ write ! ( fmt, "{}" , b) ?;
219+ }
220+ write ! ( fmt, "]" )
221+ }
182222 }
183223 }
184224}
@@ -211,8 +251,8 @@ into_array!(
211251 ( Vec <i64 >, Array :: I64 ) ,
212252 ( Vec <f64 >, Array :: F64 ) ,
213253 ( Vec <StringValue >, Array :: String ) ,
254+ ( Vec <BytesValue >, Array :: Bytes ) ,
214255) ;
215-
216256/// The value part of attribute [KeyValue] pairs.
217257#[ non_exhaustive]
218258#[ derive( Clone , Debug , PartialEq ) ]
@@ -227,6 +267,8 @@ pub enum Value {
227267 String ( StringValue ) ,
228268 /// Array of homogeneous values
229269 Array ( Array ) ,
270+ /// Bytes values
271+ Bytes ( BytesValue ) ,
230272}
231273
232274/// Wrapper for string-like values
@@ -300,6 +342,80 @@ impl From<Cow<'static, str>> for StringValue {
300342 }
301343}
302344
345+ /// Wrapper for byte array values
346+ #[ non_exhaustive]
347+ #[ derive( Clone , PartialEq , Eq , Hash ) ]
348+ pub struct BytesValue ( OtelBytes ) ;
349+
350+ impl fmt:: Debug for BytesValue {
351+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
352+ self . 0 . fmt ( f)
353+ }
354+ }
355+
356+ impl fmt:: Display for BytesValue {
357+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
358+ write ! ( f, "[" ) ?;
359+ for ( i, b) in self . as_slice ( ) . iter ( ) . enumerate ( ) {
360+ if i > 0 {
361+ write ! ( f, "," ) ?;
362+ }
363+ write ! ( f, "{:#04x}" , b) ?;
364+ }
365+ write ! ( f, "]" )
366+ }
367+ }
368+
369+ impl AsRef < [ u8 ] > for BytesValue {
370+ fn as_ref ( & self ) -> & [ u8 ] {
371+ self . 0 . as_slice ( )
372+ }
373+ }
374+
375+ impl BytesValue {
376+ /// Returns a slice to the underlying bytes
377+ pub fn as_slice ( & self ) -> & [ u8 ] {
378+ self . 0 . as_slice ( )
379+ }
380+
381+ /// Retruns a Vec<u8> from the BytesValue
382+ pub fn into_vec ( self ) -> Vec < u8 > {
383+ match self . 0 {
384+ OtelBytes :: Owned ( b) => b. to_vec ( ) ,
385+ OtelBytes :: Static ( b) => b. to_vec ( ) ,
386+ OtelBytes :: RefCounted ( b) => b. to_vec ( ) ,
387+ }
388+ }
389+ }
390+
391+ impl From < BytesValue > for Vec < u8 > {
392+ fn from ( b : BytesValue ) -> Self {
393+ match b. 0 {
394+ OtelBytes :: Owned ( b) => b. to_vec ( ) ,
395+ OtelBytes :: Static ( b) => b. to_vec ( ) ,
396+ OtelBytes :: RefCounted ( b) => b. to_vec ( ) ,
397+ }
398+ }
399+ }
400+
401+ impl From < & ' static [ u8 ] > for BytesValue {
402+ fn from ( b : & ' static [ u8 ] ) -> Self {
403+ BytesValue ( OtelBytes :: Static ( b) )
404+ }
405+ }
406+
407+ impl From < Vec < u8 > > for BytesValue {
408+ fn from ( b : Vec < u8 > ) -> Self {
409+ BytesValue ( OtelBytes :: Owned ( b) )
410+ }
411+ }
412+
413+ impl From < Arc < [ u8 ] > > for BytesValue {
414+ fn from ( b : Arc < [ u8 ] > ) -> Self {
415+ BytesValue ( OtelBytes :: RefCounted ( b) )
416+ }
417+ }
418+
303419impl Value {
304420 /// String representation of the `Value`
305421 ///
@@ -311,16 +427,13 @@ impl Value {
311427 Value :: F64 ( v) => format ! ( "{}" , v) . into ( ) ,
312428 Value :: String ( v) => Cow :: Borrowed ( v. as_str ( ) ) ,
313429 Value :: Array ( v) => format ! ( "{}" , v) . into ( ) ,
430+ Value :: Bytes ( v) => format ! ( "{}" , v) . into ( ) ,
314431 }
315432 }
316433}
317434
318435macro_rules! from_values {
319- (
320- $(
321- ( $t: ty, $val: expr) ;
322- ) +
323- ) => {
436+ ( $( ( $t: ty, $val: expr) ; ) +) => {
324437 $(
325438 impl From <$t> for Value {
326439 fn from( t: $t) -> Self {
@@ -336,6 +449,7 @@ from_values!(
336449 ( i64 , Value :: I64 ) ;
337450 ( f64 , Value :: F64 ) ;
338451 ( StringValue , Value :: String ) ;
452+ ( BytesValue , Value :: Bytes ) ;
339453) ;
340454
341455impl From < & ' static str > for Value {
@@ -362,6 +476,24 @@ impl From<Cow<'static, str>> for Value {
362476 }
363477}
364478
479+ impl From < & ' static [ u8 ] > for Value {
480+ fn from ( b : & ' static [ u8 ] ) -> Self {
481+ Value :: Bytes ( b. into ( ) )
482+ }
483+ }
484+
485+ impl From < Vec < u8 > > for Value {
486+ fn from ( b : Vec < u8 > ) -> Self {
487+ Value :: Bytes ( b. into ( ) )
488+ }
489+ }
490+
491+ impl From < Arc < [ u8 ] > > for Value {
492+ fn from ( b : Arc < [ u8 ] > ) -> Self {
493+ Value :: Bytes ( b. into ( ) )
494+ }
495+ }
496+
365497impl fmt:: Display for Value {
366498 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
367499 match self {
@@ -370,6 +502,7 @@ impl fmt::Display for Value {
370502 Value :: F64 ( v) => v. fmt ( fmt) ,
371503 Value :: String ( v) => fmt. write_str ( v. as_str ( ) ) ,
372504 Value :: Array ( v) => v. fmt ( fmt) ,
505+ Value :: Bytes ( v) => v. fmt ( fmt) ,
373506 }
374507 }
375508}
@@ -483,7 +616,6 @@ impl InstrumentationScope {
483616 self . attributes . iter ( )
484617 }
485618}
486-
487619/// Configuration options for [InstrumentationScope].
488620///
489621/// An instrumentation scope is a library or crate providing instrumentation.
0 commit comments