opentelemetry/propagation/
mod.rs1use std::collections::HashMap;
23
24pub mod composite;
25pub mod text_map_propagator;
26
27pub use composite::TextMapCompositePropagator;
28pub use text_map_propagator::TextMapPropagator;
29
30pub trait Injector {
32    fn set(&mut self, key: &str, value: String);
34}
35
36pub trait Extractor {
38    fn get(&self, key: &str) -> Option<&str>;
40
41    fn keys(&self) -> Vec<&str>;
43
44    fn get_all(&self, key: &str) -> Option<Vec<&str>> {
46        self.get(key).map(|value| vec![value])
47    }
48}
49
50impl<S: std::hash::BuildHasher> Injector for HashMap<String, String, S> {
51    fn set(&mut self, key: &str, value: String) {
53        self.insert(key.to_lowercase(), value);
54    }
55}
56
57impl<S: std::hash::BuildHasher> Extractor for HashMap<String, String, S> {
58    fn get(&self, key: &str) -> Option<&str> {
60        self.get(&key.to_lowercase()).map(|v| v.as_str())
61    }
62
63    fn keys(&self) -> Vec<&str> {
65        self.keys().map(|k| k.as_str()).collect::<Vec<_>>()
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn hash_map_get() {
75        let mut carrier = HashMap::new();
76        carrier.set("headerName", "value".to_string());
77
78        assert_eq!(
79            Extractor::get(&carrier, "HEADERNAME"),
80            Some("value"),
81            "case insensitive extraction"
82        );
83    }
84
85    #[test]
86    fn hash_map_get_all() {
87        let mut carrier = HashMap::new();
88        carrier.set("headerName", "value".to_string());
89
90        assert_eq!(
91            Extractor::get_all(&carrier, "HEADERNAME"),
92            Some(vec!["value"]),
93            "case insensitive get_all extraction"
94        );
95    }
96
97    #[test]
98    fn hash_map_get_all_missing_key() {
99        let mut carrier = HashMap::new();
100        carrier.set("headerName", "value".to_string());
101
102        assert_eq!(
103            Extractor::get_all(&carrier, "missing_key"),
104            None,
105            "case insensitive get_all extraction"
106        );
107    }
108
109    #[test]
110    fn hash_map_keys() {
111        let mut carrier = HashMap::new();
112        carrier.set("headerName1", "value1".to_string());
113        carrier.set("headerName2", "value2".to_string());
114
115        let got = Extractor::keys(&carrier);
116        assert_eq!(got.len(), 2);
117        assert!(got.contains(&"headername1"));
118        assert!(got.contains(&"headername2"));
119    }
120}