1#[cfg(feature = "ser")]
2use serde::Serialize;
3use std::cmp;
4use std::hash::{Hash, Hasher};
5
6pub type KeyName = String;
7
8#[derive(Debug, Clone)]
9#[cfg_attr(feature = "ser", derive(Serialize))]
10pub struct Key {
11 pub(crate) name: KeyName,
12 pub(crate) tags: Vec<Tag>,
13}
14
15#[derive(PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
16#[cfg_attr(feature = "ser", derive(Serialize))]
17pub struct Tag {
18 key: String,
19 value: String,
20}
21
22impl Key {
23 pub fn from_name(name: &str) -> Self {
24 Key {
25 name: name.to_owned(),
26 tags: Vec::with_capacity(0),
27 }
28 }
29
30 pub fn from(name: &str, tags: Vec<Tag>) -> Self {
31 Key {
32 name: name.to_owned(),
33 tags,
34 }
35 }
36
37 pub fn key(&self) -> &str {
38 self.name.as_str()
39 }
40
41 pub fn tags(&self) -> &[Tag] {
42 self.tags.as_slice()
43 }
44}
45
46impl PartialEq for Key {
47 fn eq(&self, other: &Self) -> bool {
48 self.name == other.name && self.tags == other.tags
49 }
50}
51
52impl Eq for Key {}
53
54impl PartialOrd for Key {
55 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
56 Some(self.cmp(other))
57 }
58}
59
60impl Ord for Key {
61 fn cmp(&self, other: &Self) -> cmp::Ordering {
62 (&self.name, &self.tags).cmp(&(&other.name, &other.tags))
63 }
64}
65
66impl Hash for Key {
67 fn hash<H: Hasher>(&self, state: &mut H) {
68 key_hasher_impl(state, &self.name, &self.tags);
69 }
70}
71
72impl Tag {
73 pub fn new(key: &str, value: &str) -> Self {
74 Self {
75 key: key.to_owned(),
76 value: value.to_owned(),
77 }
78 }
79 pub fn key(&self) -> &str {
80 self.key.as_str()
81 }
82
83 pub fn value(&self) -> &str {
84 self.value.as_str()
85 }
86}
87
88fn key_hasher_impl<H: Hasher>(state: &mut H, name: &KeyName, tags: &[Tag]) {
89 name.hash(state);
90 tags.hash(state);
91}