opentelemetry_spanprocessor_any/attributes/
mod.rs1use crate::{Array, Key, KeyValue, Value};
3use std::cmp::Ordering;
4use std::collections::{btree_map, BTreeMap};
5use std::hash::{Hash, Hasher};
6use std::iter::Peekable;
7
8mod encoder;
9pub use encoder::{default_encoder, new_encoder_id, DefaultAttributeEncoder, Encoder, EncoderId};
10
11#[derive(Clone, Debug, Default)]
13pub struct AttributeSet {
14 attributes: BTreeMap<Key, Value>,
15}
16
17impl AttributeSet {
18 pub fn from_attributes<T: IntoIterator<Item = KeyValue>>(attributes: T) -> Self {
20 AttributeSet {
21 attributes: attributes
22 .into_iter()
23 .map(|kv| (kv.key, kv.value))
24 .collect(),
25 }
26 }
27
28 pub fn len(&self) -> usize {
30 self.attributes.len()
31 }
32
33 pub fn is_empty(&self) -> bool {
35 self.attributes.is_empty()
36 }
37
38 pub fn iter(&self) -> Iter<'_> {
40 self.into_iter()
41 }
42
43 pub fn encoded(&self, encoder: Option<&dyn Encoder>) -> String {
45 encoder.map_or_else(String::new, |encoder| encoder.encode(&mut self.iter()))
46 }
47}
48
49impl<'a> IntoIterator for &'a AttributeSet {
50 type Item = (&'a Key, &'a Value);
51 type IntoIter = Iter<'a>;
52
53 fn into_iter(self) -> Self::IntoIter {
54 Iter(self.attributes.iter())
55 }
56}
57#[derive(Debug)]
59pub struct Iter<'a>(btree_map::Iter<'a, Key, Value>);
60impl<'a> Iterator for Iter<'a> {
61 type Item = (&'a Key, &'a Value);
62
63 fn next(&mut self) -> Option<Self::Item> {
64 self.0.next()
65 }
66}
67
68pub fn hash_attributes<'a, H: Hasher, I: IntoIterator<Item = (&'a Key, &'a Value)>>(
70 state: &mut H,
71 attributes: I,
72) {
73 for (key, value) in attributes.into_iter() {
74 key.hash(state);
75 hash_value(state, value);
76 }
77}
78
79fn hash_value<H: Hasher>(state: &mut H, value: &Value) {
80 match value {
81 Value::Bool(b) => b.hash(state),
82 Value::I64(i) => i.hash(state),
83 Value::F64(f) => {
84 f.to_bits().hash(state)
86 }
87 Value::String(s) => s.hash(state),
88 Value::Array(arr) => match arr {
89 Array::Bool(values) => values.iter().for_each(|v| v.hash(state)),
91 Array::I64(values) => values.iter().for_each(|v| v.hash(state)),
92 Array::F64(values) => values.iter().for_each(|v| v.to_bits().hash(state)),
93 Array::String(values) => values.iter().for_each(|v| v.hash(state)),
94 },
95 }
96}
97
98pub fn merge_iters<
100 'a,
101 'b,
102 A: Iterator<Item = (&'a Key, &'a Value)>,
103 B: Iterator<Item = (&'b Key, &'b Value)>,
104>(
105 a: A,
106 b: B,
107) -> MergeIter<'a, 'b, A, B> {
108 MergeIter {
109 a: a.peekable(),
110 b: b.peekable(),
111 }
112}
113
114#[derive(Debug)]
116pub struct MergeIter<'a, 'b, A, B>
117where
118 A: Iterator<Item = (&'a Key, &'a Value)>,
119 B: Iterator<Item = (&'b Key, &'b Value)>,
120{
121 a: Peekable<A>,
122 b: Peekable<B>,
123}
124
125impl<'a, A: Iterator<Item = (&'a Key, &'a Value)>, B: Iterator<Item = (&'a Key, &'a Value)>>
126 Iterator for MergeIter<'a, 'a, A, B>
127{
128 type Item = (&'a Key, &'a Value);
129 fn next(&mut self) -> Option<Self::Item> {
130 let which = match (self.a.peek(), self.b.peek()) {
131 (Some(a), Some(b)) => Some(a.0.cmp(b.0)),
132 (Some(_), None) => Some(Ordering::Less),
133 (None, Some(_)) => Some(Ordering::Greater),
134 (None, None) => None,
135 };
136
137 match which {
138 Some(Ordering::Less) => self.a.next(),
139 Some(Ordering::Equal) => self.a.next(),
140 Some(Ordering::Greater) => self.b.next(),
141 None => None,
142 }
143 }
144}