@@ -126,7 +126,7 @@ impl SpanId {
126
126
/// [W3C specification]: https://www.w3.org/TR/trace-context/#tracestate-header
127
127
#[ cfg_attr( feature = "serialize" , derive( Deserialize , Serialize ) ) ]
128
128
#[ derive( Clone , Debug , Default , Eq , PartialEq ) ]
129
- pub struct TraceState ( VecDeque < ( String , String ) > ) ;
129
+ pub struct TraceState ( Option < VecDeque < ( String , String ) > > ) ;
130
130
131
131
impl TraceState {
132
132
/// Validates that the given `TraceState` list-member key is valid per the [W3 Spec]['spec'].
@@ -170,7 +170,7 @@ impl TraceState {
170
170
K : ToString ,
171
171
V : ToString ,
172
172
{
173
- let ordered_data: Result < VecDeque < ( String , String ) > , ( ) > = trace_state
173
+ let ordered_data = trace_state
174
174
. into_iter ( )
175
175
. map ( |( key, value) | {
176
176
let ( key, value) = ( key. to_string ( ) , value. to_string ( ) ) ;
@@ -181,19 +181,25 @@ impl TraceState {
181
181
182
182
Ok ( ( key, value) )
183
183
} )
184
- . collect ( ) ;
184
+ . collect :: < Result < VecDeque < _ > , ( ) > > ( ) ? ;
185
185
186
- ordered_data. map ( TraceState )
186
+ if ordered_data. is_empty ( ) {
187
+ Ok ( TraceState ( None ) )
188
+ } else {
189
+ Ok ( TraceState ( Some ( ordered_data) ) )
190
+ }
187
191
}
188
192
189
193
/// Retrieves a value for a given key from the `TraceState` if it exists.
190
194
pub fn get ( & self , key : & str ) -> Option < & str > {
191
- self . 0 . iter ( ) . find_map ( |item| {
192
- if item. 0 . as_str ( ) == key {
193
- Some ( item. 1 . as_str ( ) )
194
- } else {
195
- None
196
- }
195
+ self . 0 . as_ref ( ) . and_then ( |kvs| {
196
+ kvs. iter ( ) . find_map ( |item| {
197
+ if item. 0 . as_str ( ) == key {
198
+ Some ( item. 1 . as_str ( ) )
199
+ } else {
200
+ None
201
+ }
202
+ } )
197
203
} )
198
204
}
199
205
@@ -209,8 +215,9 @@ impl TraceState {
209
215
}
210
216
211
217
let mut trace_state = self . delete ( key. clone ( ) ) ?;
218
+ let kvs = trace_state. 0 . get_or_insert ( VecDeque :: with_capacity ( 1 ) ) ;
212
219
213
- trace_state . 0 . push_front ( ( key, value) ) ;
220
+ kvs . push_front ( ( key, value) ) ;
214
221
215
222
Ok ( trace_state)
216
223
}
@@ -226,9 +233,12 @@ impl TraceState {
226
233
}
227
234
228
235
let mut owned = self . clone ( ) ;
236
+ let kvs = owned. 0 . as_mut ( ) . ok_or ( ( ) ) ?;
229
237
230
- if let Some ( index) = owned. 0 . iter ( ) . position ( |x| * x. 0 == * key) {
231
- owned. 0 . remove ( index) ;
238
+ if let Some ( index) = kvs. iter ( ) . position ( |x| * x. 0 == * key) {
239
+ kvs. remove ( index) ;
240
+ } else {
241
+ return Err ( ( ) ) ;
232
242
}
233
243
234
244
Ok ( owned)
@@ -243,10 +253,14 @@ impl TraceState {
243
253
/// Creates a new `TraceState` header string, with the given key/value delimiter and entry delimiter.
244
254
pub fn header_delimited ( & self , entry_delimiter : & str , list_delimiter : & str ) -> String {
245
255
self . 0
246
- . iter ( )
247
- . map ( |( key, value) | format ! ( "{}{}{}" , key, entry_delimiter, value) )
248
- . collect :: < Vec < String > > ( )
249
- . join ( list_delimiter)
256
+ . as_ref ( )
257
+ . map ( |kvs| {
258
+ kvs. iter ( )
259
+ . map ( |( key, value) | format ! ( "{}{}{}" , key, entry_delimiter, value) )
260
+ . collect :: < Vec < String > > ( )
261
+ . join ( list_delimiter)
262
+ } )
263
+ . unwrap_or_default ( )
250
264
}
251
265
}
252
266
0 commit comments