decode_header_value

Function decode_header_value 

Source
pub fn decode_header_value(
    value: &str,
) -> Result<Vec<(Encoding, QualityValue)>, AcceptEncodingDecodeError>
Expand description

Decodes Accept-Encoding header value into a list of encodings with quality values

Examples found in repository?
examples/basic_usage.rs (line 57)
31fn accept_encoding_examples() {
32    println!("1. Accept-Encoding Header Examples");
33    println!("==================================");
34
35    // Example 1a: Encoding Accept-Encoding header values
36    println!("\n1a. Encoding Accept-Encoding header values:");
37    let encodings = vec![
38        (Encoding::Gzip, 1.0),
39        (Encoding::Deflate, 0.8),
40        (Encoding::Br, 0.6),
41        (Encoding::Identity, 0.1),
42    ];
43
44    match encode_header_value(&encodings) {
45        Ok(header_value) => {
46            println!("   Input: {:?}", encodings);
47            println!("   Encoded header: {}", header_value);
48        }
49        Err(e) => println!("   Error encoding: {}", e),
50    }
51
52    // Example 1b: Decoding Accept-Encoding header values
53    println!("\n1b. Decoding Accept-Encoding header values:");
54    let header_string = "gzip, deflate;q=0.8, br;q=0.6, identity;q=0.1";
55    println!("   Input header: {}", header_string);
56
57    match decode_header_value(header_string) {
58        Ok(parsed) => {
59            println!("   Decoded encodings:");
60            for (encoding, quality) in parsed {
61                println!("     {} (q={})", encoding, quality);
62            }
63        }
64        Err(e) => println!("   Error decoding: {}", e),
65    }
66
67    // Example 1c: Working with complex Accept-Encoding values
68    println!("\n1c. Complex Accept-Encoding example:");
69    let complex_header = "gzip;q=1.0, deflate;q=0.5, br;q=0.25, *;q=0.1";
70    println!("   Input: {}", complex_header);
71
72    if let Ok(parsed) = decode_header_value(complex_header) {
73        // Create AcceptEncoding instance
74        if let Ok(accept_encoding) = AcceptEncoding::new(parsed) {
75            println!(
76                "   Created AcceptEncoding with {} encodings",
77                accept_encoding.items().len()
78            );
79
80            // Re-encode it
81            if let Ok(re_encoded) = encode_header_value(accept_encoding.items()) {
82                println!("   Re-encoded: {}", re_encoded);
83            }
84        }
85    }
86}
87
88/// Examples for Content-Encoding header encode/decode functionality  
89#[cfg(feature = "http_crates")]
90fn content_encoding_examples() {
91    println!("\n\n2. Content-Encoding Header Examples");
92    println!("===================================");
93
94    // Example 2a: Creating and encoding Content-Encoding headers
95    println!("\n2a. Creating and encoding Content-Encoding:");
96    let content_encoding = ContentEncoding::new(Encoding::Gzip);
97    println!("   Created ContentEncoding: {:?}", content_encoding);
98
99    // Use with HeaderMap
100    let mut headers = HeaderMap::new();
101    headers.typed_insert(content_encoding);
102
103    if let Some(header_value) = headers.get(http::header::CONTENT_ENCODING) {
104        println!(
105            "   Header value: {}",
106            header_value.to_str().unwrap_or("invalid")
107        );
108    }
109
110    // Example 2b: Decoding Content-Encoding headers
111    println!("\n2b. Decoding Content-Encoding headers:");
112    let test_values = vec!["gzip", "deflate", "br", "zstd"];
113
114    for encoding_str in test_values {
115        println!("   Testing: {}", encoding_str);
116        let header_values = vec![HeaderValue::from_str(encoding_str).unwrap()];
117
118        match ContentEncoding::decode(&mut header_values.iter()) {
119            Ok(decoded) => println!("     Decoded: {:?}", decoded),
120            Err(e) => println!("     Error: {:?}", e),
121        }
122    }
123
124    // Example 2c: Multiple identical values (valid)
125    println!("\n2c. Multiple identical Content-Encoding values:");
126    let identical_values = vec![
127        HeaderValue::from_str("gzip").unwrap(),
128        HeaderValue::from_str("gzip").unwrap(),
129    ];
130
131    match ContentEncoding::decode(&mut identical_values.iter()) {
132        Ok(decoded) => println!("   Multiple identical values decoded: {:?}", decoded),
133        Err(e) => println!("   Error: {:?}", e),
134    }
135
136    // Example 2d: Conflicting values (should error)
137    println!("\n2d. Conflicting Content-Encoding values (should error):");
138    let conflicting_values = vec![
139        HeaderValue::from_str("gzip").unwrap(),
140        HeaderValue::from_str("deflate").unwrap(),
141    ];
142
143    match ContentEncoding::decode(&mut conflicting_values.iter()) {
144        Ok(decoded) => println!("   Unexpectedly decoded: {:?}", decoded),
145        Err(_) => println!("   Correctly rejected conflicting values"),
146    }
147}
148
149#[cfg(not(feature = "http_crates"))]
150fn content_encoding_examples() {
151    println!("\n\n2. Content-Encoding Header Examples");
152    println!("===================================");
153    println!("   (Skipped - http_crates feature not enabled)");
154}
155
156/// Examples for AcceptEncoding advanced functionality
157fn accept_encoding_advanced_examples() {
158    println!("\n\n3. AcceptEncoding Advanced Usage");
159    println!("===============================");
160
161    // Create an AcceptEncoding instance with various encodings
162    let encodings = vec![
163        (Encoding::Gzip, 0.9),
164        (Encoding::Deflate, 0.8),
165        (Encoding::Br, 1.0),       // Highest quality
166        (Encoding::Identity, 0.1), // Lowest quality
167        (Encoding::Zstd, 0.7),
168    ];
169
170    let mut accept_encoding = AcceptEncoding::new(encodings).unwrap();
171    println!("\n3a. Original AcceptEncoding:");
172    println!("   Encodings: {:?}", accept_encoding.items());
173
174    // Example 3a: Finding preferred encoding
175    println!("\n3b. Finding preferred encoding:");
176    if let Some(preferred) = accept_encoding.preferred() {
177        println!("   Preferred encoding: {}", preferred);
178        println!("   (Highest quality value from unsorted list)");
179    }
180
181    // Example 3b: Sorting in descending order (highest quality first)
182    println!("\n3c. Sorting in descending order (highest quality first):");
183    accept_encoding.sort_descending();
184    println!("   After sort_descending():");
185    for (encoding, quality) in accept_encoding.items() {
186        println!("     {} (q={})", encoding, quality);
187    }
188
189    // Now preferred should be first item
190    if let Some(preferred) = accept_encoding.preferred() {
191        println!("   Preferred encoding after sorting: {}", preferred);
192        println!("   (First item in descending sorted list)");
193    }
194
195    // Example 3c: Sorting in ascending order (lowest quality first)
196    println!("\n3d. Sorting in ascending order (lowest quality first):");
197    accept_encoding.sort_ascending();
198    println!("   After sort_ascending():");
199    for (encoding, quality) in accept_encoding.items() {
200        println!("     {} (q={})", encoding, quality);
201    }
202
203    // Now preferred should be last item
204    if let Some(preferred) = accept_encoding.preferred() {
205        println!("   Preferred encoding after ascending sort: {}", preferred);
206        println!("   (Last item in ascending sorted list)");
207    }
208
209    // Example 3d: Demonstrating in-place sorting behavior
210    println!("\n3e. Demonstrating in-place sorting chain:");
211    let encodings2 = vec![
212        (Encoding::Gzip, 0.5),
213        (Encoding::Deflate, 0.9),
214        (Encoding::Br, 0.3),
215    ];
216
217    let mut accept_encoding2 = AcceptEncoding::new(encodings2).unwrap();
218    println!("   Original: {:?}", accept_encoding2.items());
219
220    // Chain sorting operations (returns &mut Self for chaining)
221    accept_encoding2.sort_descending();
222    println!("   Descending: {:?}", accept_encoding2.items());
223
224    // Sort back to ascending
225    accept_encoding2.sort_ascending();
226    println!("   Ascending: {:?}", accept_encoding2.items());
227
228    println!("\n3f. Practical example - Content negotiation:");
229    practical_content_negotiation_example();
230}
231
232/// A practical example showing how to use these functions for content negotiation
233fn practical_content_negotiation_example() {
234    // Simulate a client's Accept-Encoding header
235    let client_header = "br;q=1.0, gzip;q=0.8, deflate;q=0.6, *;q=0.1";
236    println!("   Client Accept-Encoding: {}", client_header);
237
238    // Server supported encodings (in order of preference)
239    let server_supported = vec![Encoding::Gzip, Encoding::Deflate, Encoding::Identity];
240    println!("   Server supported: {:?}", server_supported);
241
242    // Parse client preferences
243    if let Ok(client_encodings) = decode_header_value(client_header) {
244        if let Ok(mut accept_encoding) = AcceptEncoding::new(client_encodings) {
245            // Sort by client preference (highest quality first)
246            accept_encoding.sort_descending();
247
248            // Find the best match
249            let mut selected_encoding = None;
250            for (encoding, quality) in accept_encoding.items() {
251                if server_supported.contains(encoding) && *quality > 0.0 {
252                    selected_encoding = Some(encoding);
253                    break;
254                }
255            }
256
257            match selected_encoding {
258                Some(encoding) => {
259                    println!("   Selected encoding: {}", encoding);
260                    println!("   Server should use Content-Encoding: {}", encoding);
261                }
262                None => println!("   No acceptable encoding found"),
263            }
264        }
265    }
266}
More examples
Hide additional examples
examples/encode_decode.rs (line 77)
31fn accept_encoding_encode_decode_examples() {
32    println!("1. Accept-Encoding Encode/Decode");
33    println!("=================================");
34
35    // Example 1: Basic encoding
36    println!("\n1a. Basic encoding:");
37    let encodings = vec![
38        (Encoding::Gzip, 1.0),
39        (Encoding::Deflate, 0.8),
40        (Encoding::Br, 0.6),
41    ];
42
43    match encode_header_value(&encodings) {
44        Ok(encoded) => println!("   Encoded: {}", encoded),
45        Err(e) => println!("   Error: {}", e),
46    }
47
48    // Example 2: Encoding with quality value formatting
49    println!("\n1b. Quality value formatting:");
50    let encodings_with_various_qualities = vec![
51        (Encoding::Gzip, 1.0),       // q=1.0 omitted
52        (Encoding::Deflate, 0.500),  // trailing zeros trimmed
53        (Encoding::Br, 0.123),       // precise value
54        (Encoding::Identity, 0.100), // trailing zeros trimmed
55    ];
56
57    match encode_header_value(&encodings_with_various_qualities) {
58        Ok(encoded) => {
59            println!("   Input qualities: [1.0, 0.500, 0.123, 0.100]");
60            println!("   Encoded: {}", encoded);
61            println!("   (Note: q=1.0 omitted, trailing zeros trimmed)");
62        }
63        Err(e) => println!("   Error: {}", e),
64    }
65
66    // Example 3: Basic decoding
67    println!("\n1c. Basic decoding:");
68    let header_values = vec![
69        "gzip",
70        "gzip, deflate",
71        "gzip, deflate;q=0.8, br;q=0.6",
72        "br;q=1.0, gzip;q=0.8, deflate;q=0.5, *;q=0.1",
73    ];
74
75    for header in header_values {
76        println!("   Decoding: \"{}\"", header);
77        match decode_header_value(header) {
78            Ok(parsed) => {
79                println!("   Result:");
80                for (encoding, quality) in parsed {
81                    println!("     {} (q={})", encoding, quality);
82                }
83            }
84            Err(e) => println!("   Error: {}", e),
85        }
86        println!();
87    }
88
89    // Example 4: Round-trip encoding/decoding
90    println!("1d. Round-trip encoding/decoding:");
91    let original = vec![
92        (Encoding::Gzip, 1.0),
93        (Encoding::Deflate, 0.8),
94        (Encoding::Custom("custom-encoding".to_string()), 0.5),
95    ];
96
97    println!("   Original: {:?}", original);
98
99    if let Ok(encoded) = encode_header_value(&original) {
100        println!("   Encoded: {}", encoded);
101
102        if let Ok(decoded) = decode_header_value(&encoded) {
103            println!("   Decoded: {:?}", decoded);
104
105            // Verify they match
106            let matches = original.len() == decoded.len()
107                && original
108                    .iter()
109                    .zip(decoded.iter())
110                    .all(|((enc1, q1), (enc2, q2))| enc1 == enc2 && (q1 - q2).abs() < f32::EPSILON);
111            println!("   Round-trip successful: {}", matches);
112        }
113    }
114}
115
116#[cfg(feature = "http_crates")]
117fn content_encoding_examples() {
118    println!("\n\n2. Content-Encoding Examples");
119    println!("============================");
120
121    // Example 1: Creating Content-Encoding
122    println!("\n2a. Creating Content-Encoding headers:");
123    let encodings_to_test = vec![
124        Encoding::Gzip,
125        Encoding::Deflate,
126        Encoding::Br,
127        Encoding::Zstd,
128        Encoding::Custom("lz4".to_string()),
129    ];
130
131    for encoding in encodings_to_test {
132        let content_encoding = ContentEncoding::new(encoding);
133        println!("   Created: {:?}", content_encoding);
134
135        // Encode to header value
136        let mut values = Vec::new();
137        content_encoding.encode(&mut values);
138
139        if let Some(header_value) = values.first() {
140            if let Ok(as_str) = header_value.to_str() {
141                println!("     Header value: {}", as_str);
142            }
143        }
144    }
145
146    // Example 2: Decoding Content-Encoding headers
147    println!("\n2b. Decoding Content-Encoding headers:");
148    let test_headers = vec!["gzip", "deflate", "br", "zstd", "custom-encoding"];
149
150    for header_str in test_headers {
151        println!("   Decoding: \"{}\"", header_str);
152
153        let header_values = vec![HeaderValue::from_str(header_str).unwrap()];
154        match ContentEncoding::decode(&mut header_values.iter()) {
155            Ok(decoded) => {
156                println!("     Success: {:?}", decoded);
157                println!("     Encoding: {:?}", decoded.encoding());
158            }
159            Err(e) => println!("     Error: {:?}", e),
160        }
161    }
162}
163
164#[cfg(not(feature = "http_crates"))]
165fn content_encoding_examples() {
166    println!("\n\n2. Content-Encoding Examples");
167    println!("============================");
168    println!("   (Skipped - http_crates feature not enabled)");
169}
170
171fn error_handling_examples() {
172    println!("\n\n3. Error Handling Examples");
173    println!("==========================");
174
175    // Example 1: Encoding errors
176    println!("\n3a. Accept-Encoding encoding errors:");
177
178    // Empty encodings list
179    match encode_header_value(&[]) {
180        Ok(_) => println!("   Unexpected success"),
181        Err(AcceptEncodingEncodeError::EmptyEncodings) => {
182            println!("   ✓ Correctly caught empty encodings error");
183        }
184        Err(_) => println!("   Unexpected error type"),
185    }
186
187    // Example 2: Decoding errors
188    println!("\n3b. Accept-Encoding decoding errors:");
189
190    let invalid_headers = vec![
191        "",               // Empty string
192        " , gzip",        // Empty encoding name
193        ";q=1.0",         // Missing encoding name
194        "gzip;q=invalid", // Invalid quality value
195        "gzip;foo=bar",   // Unknown directive
196    ];
197
198    for invalid_header in invalid_headers {
199        println!("   Testing: \"{}\"", invalid_header);
200        match decode_header_value(invalid_header) {
201            Ok(_) => println!("     Unexpected success"),
202            Err(AcceptEncodingDecodeError::EmptyEncodingName) => {
203                println!("     ✓ Empty encoding name error");
204            }
205            Err(AcceptEncodingDecodeError::EmptyEncodingWeightTuple) => {
206                println!("     ✓ Empty encoding weight tuple error");
207            }
208            Err(AcceptEncodingDecodeError::InvalidQualityValue(val)) => {
209                println!("     ✓ Invalid quality value error: {}", val);
210            }
211            Err(AcceptEncodingDecodeError::UnexpectedDirective(directive)) => {
212                println!("     ✓ Unexpected directive error: {}", directive);
213            }
214            Err(_) => println!("     ✓ Other decode error"),
215        }
216    }
217
218    #[cfg(feature = "http_crates")]
219    {
220        // Example 3: Content-Encoding conflicting values
221        println!("\n3c. Content-Encoding conflicting values:");
222        let conflicting = vec![
223            HeaderValue::from_str("gzip").unwrap(),
224            HeaderValue::from_str("deflate").unwrap(),
225        ];
226
227        match ContentEncoding::decode(&mut conflicting.iter()) {
228            Ok(_) => println!("   Unexpected success"),
229            Err(_) => println!("   ✓ Correctly rejected conflicting Content-Encoding values"),
230        }
231    }
232}