@@ -2,12 +2,15 @@ use rand::Rng;
2
2
use std:: fmt;
3
3
4
4
use crate :: headers:: { HeaderName , HeaderValue , Headers , TRACEPARENT } ;
5
+ use crate :: Status ;
5
6
6
7
/// Extract and apply [Trace-Context](https://w3c.github.io/trace-context/) headers.
7
8
///
8
- /// ## Examples
9
+ /// # Examples
9
10
///
10
11
/// ```
12
+ /// # fn main() -> http_types::Result<()> {
13
+ /// #
11
14
/// use http_types::trace::TraceContext;
12
15
///
13
16
/// let mut res = http_types::Response::new(200);
@@ -17,14 +20,16 @@ use crate::headers::{HeaderName, HeaderValue, Headers, TRACEPARENT};
17
20
/// "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
18
21
/// );
19
22
///
20
- /// let context = TraceContext::from_headers(&res).unwrap();
23
+ /// let context = TraceContext::from_headers(&res)? .unwrap();
21
24
///
22
25
/// let trace_id = u128::from_str_radix("0af7651916cd43dd8448eb211c80319c", 16);
23
26
/// let parent_id = u64::from_str_radix("00f067aa0ba902b7", 16);
24
27
///
25
28
/// assert_eq!(context.trace_id(), trace_id.unwrap());
26
29
/// assert_eq!(context.parent_id(), parent_id.ok());
27
30
/// assert_eq!(context.sampled(), true);
31
+ /// #
32
+ /// # Ok(()) }
28
33
/// ```
29
34
#[ derive( Debug ) ]
30
35
pub struct TraceContext {
@@ -41,7 +46,7 @@ impl TraceContext {
41
46
/// By default root TraceContext objects are sampled.
42
47
/// To mark it unsampled, call `context.set_sampled(false)`.
43
48
///
44
- /// ## Examples
49
+ /// # Examples
45
50
/// ```
46
51
/// use http_types::trace::TraceContext;
47
52
///
@@ -64,8 +69,16 @@ impl TraceContext {
64
69
65
70
/// Create and return TraceContext object based on `traceparent` HTTP header.
66
71
///
67
- /// ## Examples
72
+ /// # Errors
73
+ ///
74
+ /// This function may error if the header is malformed. An error with a
75
+ /// status code of `400: Bad Request` will be generated.
76
+ ///
77
+ /// # Examples
78
+ ///
68
79
/// ```
80
+ /// # fn main() -> http_types::Result<()> {
81
+ /// #
69
82
/// use http_types::trace::TraceContext;
70
83
///
71
84
/// let mut res = http_types::Response::new(200);
@@ -74,35 +87,43 @@ impl TraceContext {
74
87
/// "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
75
88
/// );
76
89
///
77
- /// let context = TraceContext::from_headers(&res).unwrap();
90
+ /// let context = TraceContext::from_headers(&res)? .unwrap();
78
91
///
79
92
/// let trace_id = u128::from_str_radix("0af7651916cd43dd8448eb211c80319c", 16);
80
93
/// let parent_id = u64::from_str_radix("00f067aa0ba902b7", 16);
81
94
///
82
95
/// assert_eq!(context.trace_id(), trace_id.unwrap());
83
96
/// assert_eq!(context.parent_id(), parent_id.ok());
84
97
/// assert_eq!(context.sampled(), true);
98
+ /// #
99
+ /// # Ok(()) }
85
100
/// ```
86
- pub fn from_headers ( headers : impl AsRef < Headers > ) -> Option < Self > {
101
+ pub fn from_headers ( headers : impl AsRef < Headers > ) -> crate :: Result < Option < Self > > {
87
102
let headers = headers. as_ref ( ) ;
88
103
let mut rng = rand:: thread_rng ( ) ;
89
104
90
- let traceparent = headers. get ( TRACEPARENT ) ?;
105
+ let traceparent = match headers. get ( TRACEPARENT ) {
106
+ Some ( header) => header,
107
+ None => return Ok ( None ) ,
108
+ } ;
91
109
let parts: Vec < & str > = traceparent. as_str ( ) . split ( '-' ) . collect ( ) ;
92
110
93
- Some ( Self {
111
+ Ok ( Some ( Self {
94
112
id : rng. gen ( ) ,
95
- version : u8:: from_str_radix ( parts[ 0 ] , 16 ) . ok ( ) ?,
96
- trace_id : u128:: from_str_radix ( parts[ 1 ] , 16 ) . ok ( ) ?,
97
- parent_id : Some ( u64:: from_str_radix ( parts[ 2 ] , 16 ) . ok ( ) ?) ,
98
- flags : u8:: from_str_radix ( parts[ 3 ] , 16 ) . ok ( ) ?,
99
- } )
113
+ version : u8:: from_str_radix ( parts[ 0 ] , 16 ) ?,
114
+ trace_id : u128:: from_str_radix ( parts[ 1 ] , 16 ) . status ( 400 ) ?,
115
+ parent_id : Some ( u64:: from_str_radix ( parts[ 2 ] , 16 ) . status ( 400 ) ?) ,
116
+ flags : u8:: from_str_radix ( parts[ 3 ] , 16 ) . status ( 400 ) ?,
117
+ } ) )
100
118
}
101
119
102
120
/// Add the traceparent header to the http headers
103
121
///
104
- /// ## Examples
122
+ /// # Examples
123
+ ///
105
124
/// ```
125
+ /// # fn main() -> http_types::Result<()> {
126
+ /// #
106
127
/// use http_types::trace::TraceContext;
107
128
/// use http_types::{Request, Response, Url, Method};
108
129
///
@@ -112,16 +133,18 @@ impl TraceContext {
112
133
/// "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
113
134
/// );
114
135
///
115
- /// let parent = TraceContext::from_headers(&req).unwrap();
136
+ /// let parent = TraceContext::from_headers(&req)? .unwrap();
116
137
///
117
138
/// let mut res = Response::new(200);
118
139
/// parent.apply(&mut res);
119
140
///
120
- /// let child = TraceContext::from_headers(&res).unwrap();
141
+ /// let child = TraceContext::from_headers(&res)? .unwrap();
121
142
///
122
143
/// assert_eq!(child.version(), parent.version());
123
144
/// assert_eq!(child.trace_id(), parent.trace_id());
124
145
/// assert_eq!(child.parent_id(), Some(parent.id()));
146
+ /// #
147
+ /// # Ok(()) }
125
148
/// ```
126
149
pub fn apply ( & self , mut headers : impl AsMut < Headers > ) {
127
150
let headers = headers. as_mut ( ) ;
@@ -182,24 +205,28 @@ impl TraceContext {
182
205
183
206
/// Returns true if the trace is sampled
184
207
///
185
- /// ## Examples
208
+ /// # Examples
186
209
///
187
210
/// ```
211
+ /// # fn main() -> http_types::Result<()> {
212
+ /// #
188
213
/// use http_types::trace::TraceContext;
189
214
/// use http_types::Response;
190
215
///
191
216
/// let mut res = Response::new(200);
192
217
/// res.insert_header("traceparent", "00-00000000000000000000000000000001-0000000000000002-01");
193
- /// let context = TraceContext::from_headers(&res).unwrap();
218
+ /// let context = TraceContext::from_headers(&res)? .unwrap();
194
219
/// assert_eq!(context.sampled(), true);
220
+ /// #
221
+ /// # Ok(()) }
195
222
/// ```
196
223
pub fn sampled ( & self ) -> bool {
197
224
( self . flags & 0b00000001 ) == 1
198
225
}
199
226
200
227
/// Change sampled flag
201
228
///
202
- /// ## Examples
229
+ /// # Examples
203
230
///
204
231
/// ```
205
232
/// use http_types::trace::TraceContext;
@@ -233,7 +260,7 @@ mod test {
233
260
fn default ( ) -> crate :: Result < ( ) > {
234
261
let mut headers = crate :: Headers :: new ( ) ;
235
262
headers. insert ( TRACEPARENT , "00-01-deadbeef-00" ) ;
236
- let context = TraceContext :: from_headers ( & mut headers) . unwrap ( ) ;
263
+ let context = TraceContext :: from_headers ( & mut headers) ? . unwrap ( ) ;
237
264
assert_eq ! ( context. version( ) , 0 ) ;
238
265
assert_eq ! ( context. trace_id( ) , 1 ) ;
239
266
assert_eq ! ( context. parent_id( ) . unwrap( ) , 3735928559 ) ;
@@ -256,7 +283,7 @@ mod test {
256
283
fn not_sampled ( ) -> crate :: Result < ( ) > {
257
284
let mut headers = crate :: Headers :: new ( ) ;
258
285
headers. insert ( TRACEPARENT , "00-01-02-00" ) ;
259
- let context = TraceContext :: from_headers ( & mut headers) . unwrap ( ) ;
286
+ let context = TraceContext :: from_headers ( & mut headers) ? . unwrap ( ) ;
260
287
assert_eq ! ( context. sampled( ) , false ) ;
261
288
Ok ( ( ) )
262
289
}
@@ -265,7 +292,7 @@ mod test {
265
292
fn sampled ( ) -> crate :: Result < ( ) > {
266
293
let mut headers = crate :: Headers :: new ( ) ;
267
294
headers. insert ( TRACEPARENT , "00-01-02-01" ) ;
268
- let context = TraceContext :: from_headers ( & mut headers) . unwrap ( ) ;
295
+ let context = TraceContext :: from_headers ( & mut headers) ? . unwrap ( ) ;
269
296
assert_eq ! ( context. sampled( ) , true ) ;
270
297
Ok ( ( ) )
271
298
}
0 commit comments