1use crate::span::SpanContext;
3use crate::Result;
4use std::collections::{BTreeMap, HashMap};
5use std::hash::{BuildHasher, Hash};
6use std::io::{Read, Write};
7
8pub trait InjectToTextMap<T>: Sized
10where
11 T: TextMap,
12{
13 fn inject_to_text_map(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
15}
16
17pub trait ExtractFromTextMap<T>: Sized
19where
20 T: TextMap,
21{
22 fn extract_from_text_map(carrier: &T) -> Result<Option<SpanContext<Self>>>;
26}
27
28pub trait TextMap {
33 fn set(&mut self, key: &str, value: &str);
35
36 fn get(&self, key: &str) -> Option<&str>;
38}
39impl<S: BuildHasher> TextMap for HashMap<String, String, S> {
40 fn set(&mut self, key: &str, value: &str) {
41 self.insert(key.to_owned(), value.to_owned());
42 }
43 fn get(&self, key: &str) -> Option<&str> {
44 HashMap::get(self, key).map(|v| v.as_ref())
45 }
46}
47impl TextMap for BTreeMap<String, String> {
48 fn set(&mut self, key: &str, value: &str) {
49 self.insert(key.to_owned(), value.to_owned());
50 }
51 fn get(&self, key: &str) -> Option<&str> {
52 BTreeMap::get(self, key).map(|v| v.as_ref())
53 }
54}
55
56pub trait InjectToHttpHeader<T>: Sized
58where
59 T: SetHttpHeaderField,
60{
61 fn inject_to_http_header(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
63}
64
65pub trait ExtractFromHttpHeader<'a, T>: Sized
67where
68 T: IterHttpHeaderFields<'a>,
69{
70 fn extract_from_http_header(carrier: &'a T) -> Result<Option<SpanContext<Self>>>;
74}
75
76pub trait SetHttpHeaderField {
78 fn set_http_header_field(&mut self, name: &str, value: &str) -> Result<()>;
80}
81impl<S: BuildHasher> SetHttpHeaderField for HashMap<String, String, S> {
82 fn set_http_header_field(&mut self, name: &str, value: &str) -> Result<()> {
83 self.insert(name.to_owned(), value.to_owned());
84 Ok(())
85 }
86}
87
88pub trait IterHttpHeaderFields<'a> {
90 type Fields: Iterator<Item = (&'a str, &'a [u8])>;
92
93 fn fields(&'a self) -> Self::Fields;
95}
96impl<'a, K, V, S> IterHttpHeaderFields<'a> for HashMap<K, V, S>
97where
98 K: AsRef<str> + Eq + Hash,
99 V: AsRef<[u8]>,
100 S: BuildHasher,
101{
102 type Fields = Box<dyn Iterator<Item = (&'a str, &'a [u8])> + 'a>;
103
104 fn fields(&'a self) -> Self::Fields {
105 Box::new(self.iter().map(|x| (x.0.as_ref(), x.1.as_ref())))
106 }
107}
108
109pub trait InjectToBinary<T>: Sized
111where
112 T: Write,
113{
114 fn inject_to_binary(context: &SpanContext<Self>, carrier: &mut T) -> Result<()>;
116}
117
118pub trait ExtractFromBinary<T>: Sized
120where
121 T: Read,
122{
123 fn extract_from_binary(carrier: &mut T) -> Result<Option<SpanContext<Self>>>;
127}