use std::collections::HashMap;
pub trait Injector {
fn set(&mut self, key: &str, value: String);
}
pub trait Extractor {
fn get(&self, key: &str) -> Option<&str>;
#[allow(unused)]
fn keys(&self) -> Vec<&str>;
}
impl<S: std::hash::BuildHasher> Injector for HashMap<String, String, S> {
fn set(&mut self, key: &str, value: String) {
self.insert(key.to_lowercase(), value);
}
}
impl<S: std::hash::BuildHasher> Extractor for HashMap<String, String, S> {
fn get(&self, key: &str) -> Option<&str> {
self.get(&key.to_lowercase()).map(String::as_str)
}
fn keys(&self) -> Vec<&str> {
self.keys().map(String::as_str).collect::<Vec<_>>()
}
}
impl Extractor for &dyn opentelemetry::propagation::Extractor {
fn get(&self, key: &str) -> Option<&str> {
opentelemetry::propagation::Extractor::get(*self, key)
}
fn keys(&self) -> Vec<&str> {
opentelemetry::propagation::Extractor::keys(*self)
}
}
impl Injector for &mut dyn opentelemetry::propagation::Injector {
fn set(&mut self, key: &str, value: String) {
opentelemetry::propagation::Injector::set(*self, key, value);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn hash_map_get() {
let mut carrier = HashMap::new();
carrier.set("headerName", "value".to_string());
assert_eq!(
Extractor::get(&carrier, "HEADERNAME"),
Some("value"),
"case insensitive extraction"
);
}
#[test]
fn hash_map_keys() {
let mut carrier = HashMap::new();
carrier.set("headerName1", "value1".to_string());
carrier.set("headerName2", "value2".to_string());
let got = Extractor::keys(&carrier);
assert_eq!(got.len(), 2);
assert!(got.contains(&"headername1"));
assert!(got.contains(&"headername2"));
}
}