@@ -7,11 +7,12 @@ pub use entry::Entry;
7
7
use parse:: parse_header;
8
8
9
9
use std:: convert:: AsMut ;
10
+ use std:: fmt:: Write ;
10
11
use std:: iter:: Iterator ;
12
+ use std:: option;
11
13
use std:: slice;
12
14
13
- use crate :: headers:: HeaderValue ;
14
- use crate :: Headers ;
15
+ use crate :: headers:: { HeaderName , HeaderValue , Headers , ToHeaderValues , SERVER_TIMING } ;
15
16
16
17
/// Metrics and descriptions for the given request-response cycle.
17
18
///
@@ -29,10 +30,11 @@ impl ServerTiming {
29
30
pub fn new ( ) -> Self {
30
31
Self { timings : vec ! [ ] }
31
32
}
33
+
32
34
/// Create a new instance from headers.
33
35
pub fn from_headers ( headers : impl AsRef < Headers > ) -> crate :: Result < Self > {
34
36
let mut timings = vec ! [ ] ;
35
- let values = headers. as_ref ( ) . get ( "server-timing" ) ;
37
+ let values = headers. as_ref ( ) . get ( SERVER_TIMING ) ;
36
38
for value in values. iter ( ) . map ( |h| h. iter ( ) ) . flatten ( ) {
37
39
parse_header ( value. as_str ( ) , & mut timings) ?;
38
40
}
@@ -43,8 +45,26 @@ impl ServerTiming {
43
45
pub fn apply ( & self , mut headers : impl AsMut < Headers > ) {
44
46
for timing in & self . timings {
45
47
let value: HeaderValue = timing. clone ( ) . into ( ) ;
46
- headers. as_mut ( ) . insert ( "server-timing" , value) ;
48
+ headers. as_mut ( ) . insert ( SERVER_TIMING , value) ;
49
+ }
50
+ }
51
+
52
+ /// Get the `HeaderName`.
53
+ pub fn name ( & self ) -> HeaderName {
54
+ SERVER_TIMING
55
+ }
56
+
57
+ /// Get the `HeaderValue`.
58
+ pub fn value ( & self ) -> HeaderValue {
59
+ let mut output = String :: new ( ) ;
60
+ for ( n, timing) in self . timings . iter ( ) . enumerate ( ) {
61
+ let timing: HeaderValue = timing. into ( ) ;
62
+ match n {
63
+ 1 => write ! ( output, "{}" , timing) ,
64
+ _ => write ! ( output, ", {}" , timing) ,
65
+ } ;
47
66
}
67
+ output. as_ref ( ) . into ( )
48
68
}
49
69
50
70
/// Push an entry into the list of entries.
@@ -88,7 +108,7 @@ impl<'a> IntoIterator for &'a ServerTiming {
88
108
type Item = & ' a Entry ;
89
109
type IntoIter = Iter < ' a > ;
90
110
91
- #[ inline]
111
+ // #[inline]serv
92
112
fn into_iter ( self ) -> Self :: IntoIter {
93
113
self . iter ( )
94
114
}
@@ -161,6 +181,14 @@ impl<'a> Iterator for IterMut<'a> {
161
181
}
162
182
}
163
183
184
+ impl ToHeaderValues for ServerTiming {
185
+ type Iter = option:: IntoIter < HeaderValue > ;
186
+ fn to_header_values ( & self ) -> crate :: Result < Self :: Iter > {
187
+ // A HeaderValue will always convert into itself.
188
+ Ok ( self . value ( ) . to_header_values ( ) . unwrap ( ) )
189
+ }
190
+ }
191
+
164
192
#[ cfg( test) ]
165
193
mod test {
166
194
use super :: * ;
@@ -179,4 +207,18 @@ mod test {
179
207
assert_eq ! ( entry. name( ) , "server" ) ;
180
208
Ok ( ( ) )
181
209
}
210
+
211
+ #[ test]
212
+ fn to_header_values ( ) {
213
+ let mut timings = ServerTiming :: new ( ) ;
214
+ timings. push ( Entry :: new ( "server" . to_owned ( ) , None , None ) ?) ;
215
+
216
+ let mut headers = Headers :: new ( ) ;
217
+ timings. apply ( & mut headers) ;
218
+
219
+ let timings = ServerTiming :: from_headers ( headers) ?;
220
+ let entry = timings. iter ( ) . next ( ) . unwrap ( ) ;
221
+ assert_eq ! ( entry. name( ) , "server" ) ;
222
+ Ok ( ( ) )
223
+ }
182
224
}
0 commit comments