metriken_core/
metadata.rs1use std::collections::HashMap;
2use std::fmt;
3use std::iter::FusedIterator;
4
5#[derive(Clone)]
10pub struct Metadata(Impl);
11
12#[derive(Clone)]
13enum Impl {
14 Static(&'static phf::Map<&'static str, &'static str>),
15 Dynamic(HashMap<String, String>),
16}
17
18impl Metadata {
19 pub fn new(map: HashMap<String, String>) -> Self {
21 Self(Impl::Dynamic(map))
22 }
23
24 pub(crate) const fn default_const() -> Self {
25 const EMPTY_MAP: phf::Map<&str, &str> = phf::Map::new();
26
27 Self::new_static(&EMPTY_MAP)
28 }
29
30 pub(crate) const fn new_static(map: &'static phf::Map<&'static str, &'static str>) -> Self {
31 Self(Impl::Static(map))
32 }
33
34 pub fn is_empty(&self) -> bool {
36 match &self.0 {
37 Impl::Static(map) => map.is_empty(),
38 Impl::Dynamic(map) => map.is_empty(),
39 }
40 }
41
42 pub fn len(&self) -> usize {
44 match &self.0 {
45 Impl::Static(map) => map.len(),
46 Impl::Dynamic(map) => map.len(),
47 }
48 }
49
50 pub fn contains_key(&self, key: &str) -> bool {
52 match &self.0 {
53 Impl::Static(map) => map.contains_key(key),
54 Impl::Dynamic(map) => map.contains_key(key),
55 }
56 }
57
58 pub fn get(&self, key: &str) -> Option<&str> {
60 match &self.0 {
61 Impl::Static(map) => map.get(key).copied(),
62 Impl::Dynamic(map) => map.get(key).map(|s| &**s),
63 }
64 }
65
66 pub fn iter(&self) -> MetadataIter {
68 MetadataIter(match &self.0 {
69 Impl::Static(map) => IterImpl::Static(map.entries()),
70 Impl::Dynamic(map) => IterImpl::Dynamic(map.iter()),
71 })
72 }
73}
74
75impl From<HashMap<String, String>> for Metadata {
76 fn from(value: HashMap<String, String>) -> Self {
77 Self(Impl::Dynamic(value))
78 }
79}
80
81impl Default for Metadata {
82 fn default() -> Self {
83 Self::default_const()
84 }
85}
86
87impl fmt::Debug for Metadata {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match &self.0 {
90 Impl::Static(map) => map.fmt(f),
91 Impl::Dynamic(map) => map.fmt(f),
92 }
93 }
94}
95
96impl<'a> IntoIterator for &'a Metadata {
97 type Item = (&'a str, &'a str);
98 type IntoIter = MetadataIter<'a>;
99
100 fn into_iter(self) -> Self::IntoIter {
101 self.iter()
102 }
103}
104
105#[derive(Clone, Debug)]
109pub struct MetadataIter<'a>(IterImpl<'a>);
110
111impl<'a> MetadataIter<'a> {
112 fn map_entries((key, value): (&&'a str, &&'a str)) -> (&'a str, &'a str) {
113 (*key, *value)
114 }
115
116 fn map_iter((key, value): (&'a String, &'a String)) -> (&'a str, &'a str) {
117 (&**key, &**value)
118 }
119}
120
121#[derive(Clone, Debug)]
122enum IterImpl<'a> {
123 Static(phf::map::Entries<'a, &'static str, &'static str>),
124 Dynamic(std::collections::hash_map::Iter<'a, String, String>),
125}
126
127impl<'a> Iterator for MetadataIter<'a> {
128 type Item = (&'a str, &'a str);
129
130 fn next(&mut self) -> Option<Self::Item> {
131 match &mut self.0 {
132 IterImpl::Static(iter) => iter.next().map(Self::map_entries),
133 IterImpl::Dynamic(iter) => iter.next().map(Self::map_iter),
134 }
135 }
136
137 fn size_hint(&self) -> (usize, Option<usize>) {
138 match &self.0 {
139 IterImpl::Static(iter) => iter.size_hint(),
140 IterImpl::Dynamic(iter) => iter.size_hint(),
141 }
142 }
143
144 fn nth(&mut self, n: usize) -> Option<Self::Item> {
145 match &mut self.0 {
146 IterImpl::Static(iter) => iter.nth(n).map(Self::map_entries),
147 IterImpl::Dynamic(iter) => iter.nth(n).map(Self::map_iter),
148 }
149 }
150
151 fn fold<B, F>(self, init: B, mut f: F) -> B
152 where
153 Self: Sized,
154 F: FnMut(B, Self::Item) -> B,
155 {
156 match self.0 {
157 IterImpl::Static(iter) => iter.fold(init, move |acc, (k, v)| f(acc, (*k, *v))),
158 IterImpl::Dynamic(iter) => iter.fold(init, move |acc, (k, v)| f(acc, (&**k, &**v))),
159 }
160 }
161
162 fn count(self) -> usize
163 where
164 Self: Sized,
165 {
166 self.len()
167 }
168}
169
170impl<'a> ExactSizeIterator for MetadataIter<'a> {}
171
172impl<'a> FusedIterator for MetadataIter<'a> {}