1
1
//! HTTP headers.
2
2
3
- use std:: collections:: HashMap ;
4
- use std:: convert:: TryInto ;
5
- use std:: iter:: IntoIterator ;
6
-
7
3
mod constants;
8
4
mod header_name;
9
5
mod header_value;
10
6
mod header_values;
7
+ mod headers;
11
8
mod into_iter;
12
9
mod iter;
13
10
mod iter_mut;
@@ -19,176 +16,10 @@ pub use constants::*;
19
16
pub use header_name:: HeaderName ;
20
17
pub use header_value:: HeaderValue ;
21
18
pub use header_values:: HeaderValues ;
19
+ pub use headers:: Headers ;
22
20
pub use into_iter:: IntoIter ;
23
21
pub use iter:: Iter ;
24
22
pub use iter_mut:: IterMut ;
25
23
pub use names:: Names ;
26
24
pub use to_header_values:: ToHeaderValues ;
27
25
pub use values:: Values ;
28
-
29
- /// A collection of HTTP Headers.
30
- #[ derive( Debug , Clone ) ]
31
- pub struct Headers {
32
- pub ( crate ) headers : HashMap < HeaderName , HeaderValues > ,
33
- }
34
-
35
- impl Headers {
36
- /// Create a new instance.
37
- pub ( crate ) fn new ( ) -> Self {
38
- Self {
39
- headers : HashMap :: new ( ) ,
40
- }
41
- }
42
-
43
- /// Insert a header into the headers.
44
- ///
45
- /// Not that this will replace all header values for a given header name.
46
- /// If you wish to add header values for a header name that already exists
47
- /// use `Headers::append`
48
- pub fn insert (
49
- & mut self ,
50
- name : impl TryInto < HeaderName > ,
51
- values : impl ToHeaderValues ,
52
- ) -> crate :: Result < Option < HeaderValues > > {
53
- let name = name
54
- . try_into ( )
55
- . map_err ( |_| crate :: format_err!( "Could not convert into header name" ) ) ?;
56
- let values: HeaderValues = values. to_header_values ( ) ?. collect ( ) ;
57
- Ok ( self . headers . insert ( name, values) )
58
- }
59
-
60
- /// Append a header to the headers.
61
- ///
62
- /// Unlike `insert` this function will not override the contents of a header, but insert a
63
- /// header if there aren't any. Or else append to the existing list of headers.
64
- pub fn append (
65
- & mut self ,
66
- name : impl TryInto < HeaderName > ,
67
- values : impl ToHeaderValues ,
68
- ) -> crate :: Result < ( ) > {
69
- let name = name
70
- . try_into ( )
71
- . map_err ( |_| crate :: format_err!( "Could not convert into header name" ) ) ?;
72
- match self . get_mut ( & name) {
73
- Some ( headers) => {
74
- let mut values: HeaderValues = values. to_header_values ( ) ?. collect ( ) ;
75
- headers. append ( & mut values) ;
76
- }
77
- None => {
78
- self . insert ( name, values) ?;
79
- }
80
- }
81
- Ok ( ( ) )
82
- }
83
-
84
- /// Get a reference to a header.
85
- pub fn get ( & self , name : & HeaderName ) -> Option < & HeaderValues > {
86
- self . headers . get ( name)
87
- }
88
-
89
- /// Get a mutable reference to a header.
90
- pub fn get_mut ( & mut self , name : & HeaderName ) -> Option < & mut HeaderValues > {
91
- self . headers . get_mut ( name)
92
- }
93
-
94
- /// Remove a header.
95
- pub fn remove ( & mut self , name : & HeaderName ) -> Option < HeaderValues > {
96
- self . headers . remove ( name)
97
- }
98
-
99
- /// An iterator visiting all header pairs in arbitrary order.
100
- pub fn iter ( & self ) -> Iter < ' _ > {
101
- Iter {
102
- inner : self . headers . iter ( ) ,
103
- }
104
- }
105
-
106
- /// An iterator visiting all header pairs in arbitrary order, with mutable references to the
107
- /// values.
108
- pub fn iter_mut ( & mut self ) -> IterMut < ' _ > {
109
- IterMut {
110
- inner : self . headers . iter_mut ( ) ,
111
- }
112
- }
113
-
114
- /// An iterator visiting all header names in arbitrary order.
115
- pub fn names ( & self ) -> Names < ' _ > {
116
- Names {
117
- inner : self . headers . keys ( ) ,
118
- }
119
- }
120
-
121
- /// An iterator visiting all header values in arbitrary order.
122
- pub fn values ( & self ) -> Values < ' _ > {
123
- Values :: new ( self . headers . values ( ) )
124
- }
125
- }
126
-
127
- impl IntoIterator for Headers {
128
- type Item = ( HeaderName , HeaderValues ) ;
129
- type IntoIter = IntoIter ;
130
-
131
- /// Returns a iterator of references over the remaining items.
132
- #[ inline]
133
- fn into_iter ( self ) -> Self :: IntoIter {
134
- IntoIter {
135
- inner : self . headers . into_iter ( ) ,
136
- }
137
- }
138
- }
139
-
140
- impl < ' a > IntoIterator for & ' a Headers {
141
- type Item = ( & ' a HeaderName , & ' a HeaderValues ) ;
142
- type IntoIter = Iter < ' a > ;
143
-
144
- #[ inline]
145
- fn into_iter ( self ) -> Self :: IntoIter {
146
- self . iter ( )
147
- }
148
- }
149
-
150
- impl < ' a > IntoIterator for & ' a mut Headers {
151
- type Item = ( & ' a HeaderName , & ' a mut HeaderValues ) ;
152
- type IntoIter = IterMut < ' a > ;
153
-
154
- #[ inline]
155
- fn into_iter ( self ) -> Self :: IntoIter {
156
- self . iter_mut ( )
157
- }
158
- }
159
-
160
- #[ cfg( test) ]
161
- mod tests {
162
- use super :: * ;
163
- use std:: str:: FromStr ;
164
-
165
- const STATIC_HEADER : HeaderName = HeaderName :: from_lowercase_str ( "hello" ) ;
166
-
167
- #[ test]
168
- fn test_header_name_static_non_static ( ) -> crate :: Result < ( ) > {
169
- let static_header = HeaderName :: from_lowercase_str ( "hello" ) ;
170
- let non_static_header = HeaderName :: from_str ( "hello" ) ?;
171
-
172
- let mut headers = Headers :: new ( ) ;
173
- headers. append ( STATIC_HEADER , "foo0" ) ?;
174
- headers. append ( static_header. clone ( ) , "foo1" ) ?;
175
- headers. append ( non_static_header. clone ( ) , "foo2" ) ?;
176
-
177
- assert_eq ! (
178
- & headers. get( & STATIC_HEADER ) . unwrap( ) [ ..] ,
179
- & [ "foo0" , "foo1" , "foo2" , ] [ ..]
180
- ) ;
181
-
182
- assert_eq ! (
183
- & headers. get( & static_header) . unwrap( ) [ ..] ,
184
- & [ "foo0" , "foo1" , "foo2" , ] [ ..]
185
- ) ;
186
-
187
- assert_eq ! (
188
- & headers. get( & non_static_header) . unwrap( ) [ ..] ,
189
- & [ "foo0" , "foo1" , "foo2" , ] [ ..]
190
- ) ;
191
-
192
- Ok ( ( ) )
193
- }
194
- }
0 commit comments