opentelemetry_spanprocessor_any/attributes/
encoder.rs1use crate::{Key, Value};
2use std::fmt::{self, Write};
3use std::sync::atomic::{AtomicUsize, Ordering};
4
5static ENCODER_ID_COUNTER: AtomicUsize = AtomicUsize::new(0);
6
7pub trait Encoder: fmt::Debug {
12 fn encode(&self, attributes: &mut dyn Iterator<Item = (&Key, &Value)>) -> String;
15
16 fn id(&self) -> EncoderId;
19}
20
21#[derive(Debug)]
24pub struct EncoderId(usize);
25
26impl EncoderId {
27 pub fn is_valid(&self) -> bool {
29 self.0 != 0
30 }
31}
32
33#[derive(Debug)]
35pub struct DefaultAttributeEncoder;
36
37impl Encoder for DefaultAttributeEncoder {
38 fn encode(&self, attributes: &mut dyn Iterator<Item = (&Key, &Value)>) -> String {
39 attributes
40 .enumerate()
41 .fold(String::new(), |mut acc, (idx, (key, value))| {
42 let offset = acc.len();
43 if idx > 0 {
44 acc.push(',')
45 }
46
47 if write!(acc, "{}", key).is_err() {
48 acc.truncate(offset);
49 return acc;
50 }
51
52 acc.push('=');
53 if write!(acc, "{}", value).is_err() {
54 acc.truncate(offset);
55 return acc;
56 }
57
58 acc
59 })
60 }
61
62 fn id(&self) -> EncoderId {
63 new_encoder_id()
64 }
65}
66
67pub fn default_encoder() -> Box<dyn Encoder + Send + Sync> {
69 Box::new(DefaultAttributeEncoder)
70}
71
72pub fn new_encoder_id() -> EncoderId {
74 let old_encoder_id = ENCODER_ID_COUNTER.fetch_add(1, Ordering::AcqRel);
75 EncoderId(old_encoder_id + 1)
76}