1- use header:: { Header , HeaderFormat } ;
1+ use header:: { EntityTag , Header , HeaderFormat } ;
22use std:: fmt:: { self } ;
33use header:: parsing:: from_one_raw_str;
44
@@ -9,123 +9,71 @@ use header::parsing::from_one_raw_str;
99/// which always looks like this: W/
1010/// See also: https://tools.ietf.org/html/rfc7232#section-2.3
1111#[ 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 ) ;
1815
1916impl Header for Etag {
2017 fn header_name ( ) -> & ' static str {
2118 "Etag"
2219 }
2320
2421 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-
3922
4023 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 ( )
7725 } )
7826 }
7927}
8028
8129impl HeaderFormat for Etag {
8230 fn fmt_header ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
83- if self . weak {
31+ if self . 0 . weak {
8432 try!( fmt. write_str ( "W/" ) ) ;
8533 }
86- write ! ( fmt, "\" {}\" " , self . tag)
34+ write ! ( fmt, "\" {}\" " , self . 0 . tag)
8735 }
8836}
8937
9038#[ cfg( test) ]
9139mod tests {
9240 use super :: Etag ;
93- use header:: Header ;
41+ use header:: { Header , EntityTag } ;
9442
9543 #[ test]
9644 fn test_etag_successes ( ) {
9745 // Expected successes
9846 let mut etag: Option < Etag > ;
9947
10048 etag = Header :: parse_header ( [ b"\" foobar\" " . to_vec ( ) ] . as_slice ( ) ) ;
101- assert_eq ! ( etag, Some ( Etag {
49+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
10250 weak: false ,
10351 tag: "foobar" . to_string( )
104- } ) ) ;
52+ } ) ) ) ;
10553
10654 etag = Header :: parse_header ( [ b"\" \" " . to_vec ( ) ] . as_slice ( ) ) ;
107- assert_eq ! ( etag, Some ( Etag {
55+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
10856 weak: false ,
10957 tag: "" . to_string( )
110- } ) ) ;
58+ } ) ) ) ;
11159
11260 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 {
11462 weak: true ,
11563 tag: "weak-etag" . to_string( )
116- } ) ) ;
64+ } ) ) ) ;
11765
11866 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 {
12068 weak: true ,
12169 tag: "\u{0065} \u{0062} " . to_string( )
122- } ) ) ;
70+ } ) ) ) ;
12371
12472 etag = Header :: parse_header ( [ b"W/\" \" " . to_vec ( ) ] . as_slice ( ) ) ;
125- assert_eq ! ( etag, Some ( Etag {
73+ assert_eq ! ( etag, Some ( Etag ( EntityTag {
12674 weak: true ,
12775 tag: "" . to_string( )
128- } ) ) ;
76+ } ) ) ) ;
12977 }
13078
13179 #[ test]
0 commit comments