1
- use header:: { Header , HeaderFormat } ;
1
+ use header:: { EntityTag , Header , HeaderFormat } ;
2
2
use std:: fmt:: { self } ;
3
3
use header:: parsing:: from_one_raw_str;
4
4
@@ -9,123 +9,71 @@ use header::parsing::from_one_raw_str;
9
9
/// which always looks like this: W/
10
10
/// See also: https://tools.ietf.org/html/rfc7232#section-2.3
11
11
#[ derive( Clone , PartialEq , Debug ) ]
12
- pub struct Etag {
13
- /// Weakness indicator for the tag
14
- pub weak : bool ,
15
- /// The opaque string in between the DQUOTEs
16
- pub tag : String
17
- }
12
+ pub struct Etag ( pub EntityTag ) ;
13
+
14
+ deref ! ( Etag => EntityTag ) ;
18
15
19
16
impl Header for Etag {
20
17
fn header_name ( ) -> & ' static str {
21
18
"Etag"
22
19
}
23
20
24
21
fn parse_header ( raw : & [ Vec < u8 > ] ) -> Option < Etag > {
25
- // check that each char in the slice is either:
26
- // 1. %x21, or
27
- // 2. in the range %x23 to %x7E, or
28
- // 3. in the range %x80 to %xFF
29
- fn check_slice_validity ( slice : & str ) -> bool {
30
- for c in slice. bytes ( ) {
31
- match c {
32
- b'\x21' | b'\x23' ... b'\x7e' | b'\x80' ... b'\xff' => ( ) ,
33
- _ => { return false ; }
34
- }
35
- }
36
- true
37
- }
38
-
39
22
40
23
from_one_raw_str ( raw) . and_then ( |s : String | {
41
- let length: usize = s. len ( ) ;
42
- let slice = & s[ ] ;
43
-
44
- // Early exits:
45
- // 1. The string is empty, or,
46
- // 2. it doesn't terminate in a DQUOTE.
47
- if slice. is_empty ( ) || !slice. ends_with ( "\" " ) {
48
- return None ;
49
- }
50
-
51
- // The etag is weak if its first char is not a DQUOTE.
52
- if slice. char_at ( 0 ) == '"' {
53
- // No need to check if the last char is a DQUOTE,
54
- // we already did that above.
55
- if check_slice_validity ( slice. slice_chars ( 1 , length-1 ) ) {
56
- return Some ( Etag {
57
- weak : false ,
58
- tag : slice. slice_chars ( 1 , length-1 ) . to_string ( )
59
- } ) ;
60
- } else {
61
- return None ;
62
- }
63
- }
64
-
65
- if slice. slice_chars ( 0 , 3 ) == "W/\" " {
66
- if check_slice_validity ( slice. slice_chars ( 3 , length-1 ) ) {
67
- return Some ( Etag {
68
- weak : true ,
69
- tag : slice. slice_chars ( 3 , length-1 ) . to_string ( )
70
- } ) ;
71
- } else {
72
- return None ;
73
- }
74
- }
75
-
76
- None
24
+ s. parse :: < EntityTag > ( ) . and_then ( |x| Ok ( Etag ( x) ) ) . ok ( )
77
25
} )
78
26
}
79
27
}
80
28
81
29
impl HeaderFormat for Etag {
82
30
fn fmt_header ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
83
- if self . weak {
31
+ if self . 0 . weak {
84
32
try!( fmt. write_str ( "W/" ) ) ;
85
33
}
86
- write ! ( fmt, "\" {}\" " , self . tag)
34
+ write ! ( fmt, "\" {}\" " , self . 0 . tag)
87
35
}
88
36
}
89
37
90
38
#[ cfg( test) ]
91
39
mod tests {
92
40
use super :: Etag ;
93
- use header:: Header ;
41
+ use header:: { Header , EntityTag } ;
94
42
95
43
#[ test]
96
44
fn test_etag_successes ( ) {
97
45
// Expected successes
98
46
let mut etag: Option < Etag > ;
99
47
100
48
etag = Header :: parse_header ( [ b"\" foobar\" " . to_vec ( ) ] . as_slice ( ) ) ;
101
- assert_eq ! ( etag, Some ( Etag {
49
+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
102
50
weak: false ,
103
51
tag: "foobar" . to_string( )
104
- } ) ) ;
52
+ } ) ) ) ;
105
53
106
54
etag = Header :: parse_header ( [ b"\" \" " . to_vec ( ) ] . as_slice ( ) ) ;
107
- assert_eq ! ( etag, Some ( Etag {
55
+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
108
56
weak: false ,
109
57
tag: "" . to_string( )
110
- } ) ) ;
58
+ } ) ) ) ;
111
59
112
60
etag = Header :: parse_header ( [ b"W/\" weak-etag\" " . to_vec ( ) ] . as_slice ( ) ) ;
113
- assert_eq ! ( etag, Some ( Etag {
61
+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
114
62
weak: true ,
115
63
tag: "weak-etag" . to_string( )
116
- } ) ) ;
64
+ } ) ) ) ;
117
65
118
66
etag = Header :: parse_header ( [ b"W/\" \x65 \x62 \" " . to_vec ( ) ] . as_slice ( ) ) ;
119
- assert_eq ! ( etag, Some ( Etag {
67
+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
120
68
weak: true ,
121
69
tag: "\u{0065} \u{0062} " . to_string( )
122
- } ) ) ;
70
+ } ) ) ) ;
123
71
124
72
etag = Header :: parse_header ( [ b"W/\" \" " . to_vec ( ) ] . as_slice ( ) ) ;
125
- assert_eq ! ( etag, Some ( Etag {
73
+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
126
74
weak: true ,
127
75
tag: "" . to_string( )
128
- } ) ) ;
76
+ } ) ) ) ;
129
77
}
130
78
131
79
#[ test]
0 commit comments