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
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}