use crate::span::SpanContext;
use crate::Result;
use std::collections::{BTreeMap, HashMap};
use std::hash::{BuildHasher, Hash};
use std::io::{Read, Write};
pub trait InjectToTextMap<T>: Sized
where
T: TextMap,
{
fn inject_to_text_map(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
}
pub trait ExtractFromTextMap<T>: Sized
where
T: TextMap,
{
fn extract_from_text_map(carrier: &T) -> Result<Option<SpanContext<Self>>>;
}
pub trait TextMap {
fn set(&mut self, key: &str, value: &str);
fn get(&self, key: &str) -> Option<&str>;
}
impl<S: BuildHasher> TextMap for HashMap<String, String, S> {
fn set(&mut self, key: &str, value: &str) {
self.insert(key.to_owned(), value.to_owned());
}
fn get(&self, key: &str) -> Option<&str> {
HashMap::get(self, key).map(|v| v.as_ref())
}
}
impl TextMap for BTreeMap<String, String> {
fn set(&mut self, key: &str, value: &str) {
self.insert(key.to_owned(), value.to_owned());
}
fn get(&self, key: &str) -> Option<&str> {
BTreeMap::get(self, key).map(|v| v.as_ref())
}
}
pub trait InjectToHttpHeader<T>: Sized
where
T: SetHttpHeaderField,
{
fn inject_to_http_header(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
}
pub trait ExtractFromHttpHeader<'a, T>: Sized
where
T: IterHttpHeaderFields<'a>,
{
fn extract_from_http_header(carrier: &'a T) -> Result<Option<SpanContext<Self>>>;
}
pub trait SetHttpHeaderField {
fn set_http_header_field(&mut self, name: &str, value: &str) -> Result<()>;
}
impl<S: BuildHasher> SetHttpHeaderField for HashMap<String, String, S> {
fn set_http_header_field(&mut self, name: &str, value: &str) -> Result<()> {
self.insert(name.to_owned(), value.to_owned());
Ok(())
}
}
pub trait IterHttpHeaderFields<'a> {
type Fields: Iterator<Item = (&'a str, &'a [u8])>;
fn fields(&'a self) -> Self::Fields;
}
impl<'a, K, V, S> IterHttpHeaderFields<'a> for HashMap<K, V, S>
where
K: AsRef<str> + Eq + Hash,
V: AsRef<[u8]>,
S: BuildHasher,
{
type Fields = Box<dyn Iterator<Item = (&'a str, &'a [u8])> + 'a>;
fn fields(&'a self) -> Self::Fields {
Box::new(self.iter().map(|x| (x.0.as_ref(), x.1.as_ref())))
}
}
pub trait InjectToBinary<T>: Sized
where
T: Write,
{
fn inject_to_binary(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
}
pub trait ExtractFromBinary<T>: Sized
where
T: Read,
{
fn extract_from_binary(carrier: &mut T) -> Result<Option<SpanContext<Self>>>;
}