@@ -413,6 +413,55 @@ impl KeyValue {
413413 }
414414}
415415
416+ /// Create a new `KeyValue` from a key and value tuple.
417+ impl < K , V > From < ( K , V ) > for KeyValue
418+ where
419+ K : Into < Key > ,
420+ V : Into < Value > ,
421+ {
422+ fn from ( tuple : ( K , V ) ) -> Self {
423+ KeyValue :: new ( tuple. 0 , tuple. 1 )
424+ }
425+ }
426+
427+
428+ /// Represents a collector for `KeyValue` attributes.
429+ #[ derive( Default , Debug ) ]
430+ pub struct KeyValueCollector {
431+ vec : Vec < KeyValue > ,
432+ }
433+
434+ impl KeyValueCollector {
435+ /// Adds a key-value pair to the collector.
436+ pub fn add < K , V > ( & mut self , key : K , value : V )
437+ where
438+ K : Into < Key > ,
439+ V : Into < Value > ,
440+ {
441+ self . add_kv ( ( key, value) ) ;
442+ }
443+
444+ /// Adds a `KeyValue` to the collector.
445+ pub fn add_kv < KV > ( & mut self , kv : KV )
446+ where KV : Into < KeyValue >
447+ {
448+ self . vec . push ( kv. into ( ) ) ;
449+ }
450+ }
451+
452+ /// A trait for types that can be converted to a set of `KeyValue` attributes.
453+ pub trait AsKeyValues {
454+ /// Returns a vector of `KeyValue` attributes.
455+ fn as_key_values ( & self ) -> Vec < KeyValue > {
456+ let mut collector = KeyValueCollector :: default ( ) ;
457+ self . collect_key_values ( & mut collector) ;
458+ collector. vec
459+ }
460+
461+ /// Collects key-value pairs into the provided `KeyValueCollector`.
462+ fn collect_key_values ( & self , collector : & mut KeyValueCollector ) ;
463+ }
464+
416465struct F64Hashable ( f64 ) ;
417466
418467impl PartialEq for F64Hashable {
@@ -628,7 +677,7 @@ impl InstrumentationScopeBuilder {
628677mod tests {
629678 use std:: hash:: { Hash , Hasher } ;
630679
631- use crate :: { InstrumentationScope , KeyValue } ;
680+ use crate :: { InstrumentationScope , KeyValue , AsKeyValues , KeyValueCollector } ;
632681
633682 use rand:: random;
634683 use std:: collections:: hash_map:: DefaultHasher ;
@@ -701,6 +750,33 @@ mod tests {
701750 hasher. finish ( )
702751 }
703752
753+ #[ test]
754+ fn kv_from_tuple ( ) {
755+ let kv: KeyValue = ( "key" , "value" ) . into ( ) ;
756+ assert_eq ! ( kv. key. as_str( ) , "key" ) ;
757+ assert_eq ! ( kv. value. as_str( ) , "value" ) ;
758+ }
759+
760+ struct HelperStruct ;
761+
762+ impl AsKeyValues for HelperStruct {
763+ fn collect_key_values ( & self , collector : & mut KeyValueCollector ) {
764+ collector. add ( "key1" , "value1" ) ;
765+ collector. add_kv ( ( "key2" , "value2" ) ) ;
766+ }
767+ }
768+
769+ #[ test]
770+ fn kv_collector ( ) {
771+ let helper = HelperStruct ;
772+ let kvs = helper. as_key_values ( ) ;
773+ assert_eq ! ( kvs. len( ) , 2 ) ;
774+ assert_eq ! ( kvs[ 0 ] . key. as_str( ) , "key1" ) ;
775+ assert_eq ! ( kvs[ 0 ] . value. as_str( ) , "value1" ) ;
776+ assert_eq ! ( kvs[ 1 ] . key. as_str( ) , "key2" ) ;
777+ assert_eq ! ( kvs[ 1 ] . value. as_str( ) , "value2" ) ;
778+ }
779+
704780 #[ test]
705781 fn instrumentation_scope_equality ( ) {
706782 let scope1 = InstrumentationScope :: builder ( "my-crate" )
0 commit comments