@@ -532,12 +532,9 @@ pub struct Label {
532532
533533impl Label {
534534 /// Create a new [`Label`]
535- pub fn new (
536- name : impl Into < Cow < ' static , str > > ,
537- value : impl Into < Cow < ' static , str > > ,
538- ) -> Self {
539- let name = LabelValue :: from ( name. into ( ) ) ;
540- let value = LabelValue :: from ( value. into ( ) ) ;
535+ pub fn new ( name : impl Into < LabelValue > , value : impl Into < LabelValue > ) -> Self {
536+ let name = name. into ( ) ;
537+ let value = value. into ( ) ;
541538 Self { name, value }
542539 }
543540
@@ -558,32 +555,55 @@ impl Display for Label {
558555 }
559556}
560557
561- /// Internal representation for label names and values .
558+ /// A label name or value .
562559///
563- /// `Static` preserves the existing allocation-free path for string literals.
564- /// `Shared` stores dynamic strings behind [`Arc<str>`], so cloning a [`Label`]
565- /// only increments an atomic reference count and does not allocate or copy the
566- /// underlying string data.
567- #[ derive( Clone , Eq ) ]
568- enum LabelValue {
560+ /// String literals preserve the existing allocation-free path. Dynamic strings
561+ /// can be stored behind [`Arc<str>`], so cloning a [`Label`] only increments an
562+ /// atomic reference count and does not allocate or copy the underlying string
563+ /// data.
564+ #[ derive( Clone ) ]
565+ pub struct LabelValue ( LabelValueInner ) ;
566+
567+ /// Internal representation for label names and values.
568+ #[ derive( Clone ) ]
569+ enum LabelValueInner {
569570 Static ( & ' static str ) ,
570571 Shared ( Arc < str > ) ,
571572}
572573
573574impl LabelValue {
574- fn as_str ( & self ) -> & str {
575- match self {
576- Self :: Static ( value) => value,
577- Self :: Shared ( value) => value. as_ref ( ) ,
575+ /// Return this label value as a string slice.
576+ pub fn as_str ( & self ) -> & str {
577+ match & self . 0 {
578+ LabelValueInner :: Static ( value) => value,
579+ LabelValueInner :: Shared ( value) => value. as_ref ( ) ,
578580 }
579581 }
580582}
581583
584+ impl From < & ' static str > for LabelValue {
585+ fn from ( value : & ' static str ) -> Self {
586+ Self ( LabelValueInner :: Static ( value) )
587+ }
588+ }
589+
590+ impl From < String > for LabelValue {
591+ fn from ( value : String ) -> Self {
592+ Self ( LabelValueInner :: Shared ( Arc :: from ( value) ) )
593+ }
594+ }
595+
596+ impl From < Arc < str > > for LabelValue {
597+ fn from ( value : Arc < str > ) -> Self {
598+ Self ( LabelValueInner :: Shared ( value) )
599+ }
600+ }
601+
582602impl From < Cow < ' static , str > > for LabelValue {
583603 fn from ( value : Cow < ' static , str > ) -> Self {
584604 match value {
585- Cow :: Borrowed ( value) => Self :: Static ( value) ,
586- Cow :: Owned ( value) => Self :: Shared ( Arc :: from ( value) ) ,
605+ Cow :: Borrowed ( value) => value. into ( ) ,
606+ Cow :: Owned ( value) => value. into ( ) ,
587607 }
588608 }
589609}
@@ -594,6 +614,8 @@ impl PartialEq for LabelValue {
594614 }
595615}
596616
617+ impl Eq for LabelValue { }
618+
597619impl Hash for LabelValue {
598620 fn hash < H : Hasher > ( & self , state : & mut H ) {
599621 self . as_str ( ) . hash ( state) ;
@@ -670,9 +692,12 @@ mod tests {
670692 fn test_label_owned_and_borrowed_values_are_equal ( ) {
671693 let borrowed = Label :: new ( "foo" , "bar" ) ;
672694 let owned = Label :: new ( "foo" . to_string ( ) , "bar" . to_string ( ) ) ;
695+ let shared = Label :: new ( "foo" , Arc :: < str > :: from ( "bar" ) ) ;
673696
674697 assert_eq ! ( borrowed, owned) ;
698+ assert_eq ! ( borrowed, shared) ;
675699 assert_eq ! ( borrowed. to_string( ) , owned. to_string( ) ) ;
700+ assert_eq ! ( borrowed. to_string( ) , shared. to_string( ) ) ;
676701 }
677702
678703 #[ test]
0 commit comments