1use std::slice::Iter;
2
3use crate::SharedString;
4
5#[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
16pub struct Label(pub(crate) SharedString, pub(crate) SharedString);
17
18impl Label {
19 pub fn new<K, V>(key: K, value: V) -> Self
21 where
22 K: Into<SharedString>,
23 V: Into<SharedString>,
24 {
25 Label(key.into(), value.into())
26 }
27
28 pub const fn from_static_parts(key: &'static str, value: &'static str) -> Self {
30 Label(SharedString::const_str(key), SharedString::const_str(value))
31 }
32
33 pub fn key(&self) -> &str {
35 self.0.as_ref()
36 }
37
38 pub fn value(&self) -> &str {
40 self.1.as_ref()
41 }
42
43 pub fn into_parts(self) -> (SharedString, SharedString) {
45 (self.0, self.1)
46 }
47}
48
49impl<K, V> From<&(K, V)> for Label
50where
51 K: Into<SharedString> + Clone,
52 V: Into<SharedString> + Clone,
53{
54 fn from(pair: &(K, V)) -> Label {
55 Label::new(pair.0.clone(), pair.1.clone())
56 }
57}
58
59impl<K, V> From<(&K, &V)> for Label
60where
61 K: Into<SharedString> + Clone,
62 V: Into<SharedString> + Clone,
63{
64 fn from(pair: (&K, &V)) -> Label {
65 Label::new(pair.0.clone(), pair.1.clone())
66 }
67}
68
69pub trait IntoLabels {
71 fn into_labels(self) -> Vec<Label>;
73}
74
75impl IntoLabels for Vec<Label> {
76 fn into_labels(self) -> Vec<Label> {
77 self
78 }
79}
80
81impl IntoLabels for Iter<'_, Label> {
82 fn into_labels(self) -> Vec<Label> {
83 self.cloned().collect()
84 }
85}
86
87impl<T: ?Sized, L> IntoLabels for &T
88where
89 Self: IntoIterator<Item = L>,
90 L: Into<Label>,
91{
92 fn into_labels(self) -> Vec<Label> {
93 self.into_iter().map(|l| l.into()).collect()
94 }
95}
96
97#[cfg(test)]
98mod label_tests {
99 use super::*;
100
101 #[test]
102 fn slice_labels() {
103 let labels = [("x", "a"), ("y", "b")];
104
105 fn from_slice_to_labels(labels: &[(&'static str, &'static str)]) -> Vec<Label> {
106 labels.into_labels()
107 }
108
109 let expected = vec![Label::new("x", "a"), Label::new("y", "b")];
110 assert_eq!(from_slice_to_labels(&labels), expected);
111 }
112
113 #[test]
114 fn btreemap_to_labels() {
115 use std::collections::BTreeMap;
116
117 let labels_btreemap = BTreeMap::from([("customer", "Rust Foundation")]);
118
119 let expected = vec![Label::new("customer", "Rust Foundation")];
120 assert_eq!(labels_btreemap.into_labels(), expected);
121 }
122}