@@ -26,8 +26,6 @@ impl ByteRange {
2626 ByteRange :: From ( s) => format ! ( "bytes={s}-" ) ,
2727 ByteRange :: Last ( n) => format ! ( "bytes=-{n}" ) ,
2828 } ;
29- // SAFETY: the format only contains ASCII digits, hyphens, and the
30- // literal prefix "bytes=", which are all valid header value bytes.
3129 HeaderValue :: from_str ( & s) . expect ( "ByteRange always produces a valid header value" )
3230 }
3331
@@ -168,10 +166,8 @@ impl ContentRange {
168166 /// The returned value is always valid ASCII and can be inserted directly
169167 /// into an HTTP header map.
170168 pub fn to_header_value ( & self ) -> HeaderValue {
171- let s = format ! ( "bytes {}-{}/{}" , self . start, self . end, self . total) ;
172- // SAFETY: the format only contains ASCII digits, spaces, hyphens,
173- // and slashes, which are all valid header value bytes.
174- HeaderValue :: from_str ( & s) . expect ( "ContentRange always produces a valid header value" )
169+ HeaderValue :: from_str ( & self . to_string ( ) )
170+ . expect ( "ContentRange always produces a valid header value" )
175171 }
176172}
177173
@@ -212,33 +208,14 @@ mod tests {
212208 use super :: * ;
213209
214210 #[ test]
215- fn parse_from_to ( ) {
211+ fn parse_valid_ranges ( ) {
216212 assert_eq ! (
217213 ByteRange :: try_from( "bytes=0-499" ) ,
218214 Ok ( ByteRange :: Inclusive ( 0 , 499 ) )
219215 ) ;
220- }
221-
222- #[ test]
223- fn parse_from ( ) {
224216 assert_eq ! ( ByteRange :: try_from( "bytes=500-" ) , Ok ( ByteRange :: From ( 500 ) ) ) ;
225- }
226-
227- #[ test]
228- fn parse_suffix ( ) {
229217 assert_eq ! ( ByteRange :: try_from( "bytes=-100" ) , Ok ( ByteRange :: Last ( 100 ) ) ) ;
230- }
231-
232- #[ test]
233- fn parse_rejects_multi_range ( ) {
234- assert_eq ! (
235- ByteRange :: try_from( "bytes=0-10, 20-30" ) ,
236- Err ( RangeError :: MultiRangeNotSupported )
237- ) ;
238- }
239-
240- #[ test]
241- fn parse_case_insensitive ( ) {
218+ // Case insensitive
242219 assert_eq ! (
243220 ByteRange :: try_from( "Bytes=0-499" ) ,
244221 Ok ( ByteRange :: Inclusive ( 0 , 499 ) )
@@ -247,86 +224,33 @@ mod tests {
247224 }
248225
249226 #[ test]
250- fn parse_returns_unknown_unit_for_non_bytes ( ) {
251- assert_eq ! ( ByteRange :: try_from( "items=0-10" ) , Err ( RangeError :: UnknownUnit ) ) ;
252- }
253-
254- #[ test]
255- fn parse_rejects_inverted_range ( ) {
227+ fn parse_invalid_ranges ( ) {
256228 assert_eq ! (
257- ByteRange :: try_from( "bytes=500-100 " ) ,
258- Err ( RangeError :: InvalidRange )
229+ ByteRange :: try_from( "bytes=0-10, 20-30 " ) ,
230+ Err ( RangeError :: MultiRangeNotSupported )
259231 ) ;
260- }
261-
262- #[ test]
263- fn parse_rejects_zero_suffix ( ) {
264- assert_eq ! ( ByteRange :: try_from( "bytes=-0" ) , Err ( RangeError :: InvalidRange ) ) ;
265- }
266-
267- #[ test]
268- fn resolve_from_to ( ) {
269- let range = ByteRange :: Inclusive ( 0 , 499 ) . resolve ( 1000 ) ;
270232 assert_eq ! (
271- range,
272- Some ( ContentRange {
273- start: 0 ,
274- end: 499 ,
275- total: 1000
276- } )
233+ ByteRange :: try_from( "items=0-10" ) ,
234+ Err ( RangeError :: UnknownUnit )
277235 ) ;
278- }
279-
280- #[ test]
281- fn resolve_from_to_clamped ( ) {
282- let range = ByteRange :: Inclusive ( 0 , 9999 ) . resolve ( 500 ) ;
283236 assert_eq ! (
284- range,
285- Some ( ContentRange {
286- start: 0 ,
287- end: 499 ,
288- total: 500
289- } )
290- ) ;
291- }
292-
293- #[ test]
294- fn resolve_from ( ) {
295- let range = ByteRange :: From ( 500 ) . resolve ( 1000 ) ;
296- assert_eq ! (
297- range,
298- Some ( ContentRange {
299- start: 500 ,
300- end: 999 ,
301- total: 1000
302- } )
237+ ByteRange :: try_from( "bytes=500-100" ) ,
238+ Err ( RangeError :: InvalidRange )
303239 ) ;
304- }
305-
306- #[ test]
307- fn resolve_suffix ( ) {
308- let range = ByteRange :: Last ( 100 ) . resolve ( 1000 ) ;
309240 assert_eq ! (
310- range,
311- Some ( ContentRange {
312- start: 900 ,
313- end: 999 ,
314- total: 1000
315- } )
241+ ByteRange :: try_from( "bytes=-0" ) ,
242+ Err ( RangeError :: InvalidRange )
316243 ) ;
317244 }
318245
319246 #[ test]
320- fn resolve_suffix_larger_than_total ( ) {
321- let range = ByteRange :: Last ( 2000 ) . resolve ( 1000 ) ;
322- assert_eq ! (
323- range,
324- Some ( ContentRange {
325- start: 0 ,
326- end: 999 ,
327- total: 1000
328- } )
329- ) ;
247+ fn resolve_satisfiable ( ) {
248+ let cr = |start, end, total| Some ( ContentRange { start, end, total } ) ;
249+ assert_eq ! ( ByteRange :: Inclusive ( 0 , 499 ) . resolve( 1000 ) , cr( 0 , 499 , 1000 ) ) ;
250+ assert_eq ! ( ByteRange :: Inclusive ( 0 , 9999 ) . resolve( 500 ) , cr( 0 , 499 , 500 ) ) ;
251+ assert_eq ! ( ByteRange :: From ( 500 ) . resolve( 1000 ) , cr( 500 , 999 , 1000 ) ) ;
252+ assert_eq ! ( ByteRange :: Last ( 100 ) . resolve( 1000 ) , cr( 900 , 999 , 1000 ) ) ;
253+ assert_eq ! ( ByteRange :: Last ( 2000 ) . resolve( 1000 ) , cr( 0 , 999 , 1000 ) ) ;
330254 }
331255
332256 #[ test]
@@ -337,60 +261,54 @@ mod tests {
337261 }
338262
339263 #[ test]
340- fn content_range_full ( ) {
341- let cr = ContentRange :: full ( 1000 ) ;
342- assert_eq ! ( cr. start, 0 ) ;
343- assert_eq ! ( cr. end, 999 ) ;
344- assert_eq ! ( cr. total, 1000 ) ;
345- assert_eq ! ( cr. len( ) , 1000 ) ;
346- assert ! ( cr. is_full( ) ) ;
347- assert_eq ! ( cr. to_header_value( ) , "bytes 0-999/1000" ) ;
348- }
264+ fn content_range_properties ( ) {
265+ let full = ContentRange :: full ( 1000 ) ;
266+ assert_eq ! (
267+ full,
268+ ContentRange {
269+ start: 0 ,
270+ end: 999 ,
271+ total: 1000
272+ }
273+ ) ;
274+ assert_eq ! ( full. len( ) , 1000 ) ;
275+ assert ! ( full. is_full( ) ) ;
349276
350- #[ test]
351- fn content_range_partial_is_not_full ( ) {
352- let cr = ContentRange {
277+ let partial = ContentRange {
353278 start : 0 ,
354279 end : 499 ,
355280 total : 1000 ,
356281 } ;
357- assert ! ( !cr. is_full( ) ) ;
358- assert_eq ! ( cr. len( ) , 500 ) ;
359- }
282+ assert_eq ! ( partial. len( ) , 500 ) ;
283+ assert ! ( !partial. is_full( ) ) ;
360284
361- #[ test]
362- fn content_range_full_zero_bytes ( ) {
363- let cr = ContentRange :: full ( 0 ) ;
364- assert_eq ! ( cr. len( ) , 0 ) ;
365- assert ! ( cr. is_full( ) ) ;
285+ let zero = ContentRange :: full ( 0 ) ;
286+ assert_eq ! ( zero. len( ) , 0 ) ;
287+ assert ! ( zero. is_full( ) ) ;
366288 }
367289
368290 #[ test]
369- fn byte_range_to_header_value ( ) {
291+ fn header_value_roundtrips ( ) {
370292 assert_eq ! (
371293 ByteRange :: Inclusive ( 0 , 499 ) . to_header_value( ) ,
372294 "bytes=0-499"
373295 ) ;
374296 assert_eq ! ( ByteRange :: From ( 500 ) . to_header_value( ) , "bytes=500-" ) ;
375297 assert_eq ! ( ByteRange :: Last ( 100 ) . to_header_value( ) , "bytes=-100" ) ;
376- }
377298
378- #[ test]
379- fn content_range_parse ( ) {
380- assert_eq ! (
381- ContentRange :: parse( "bytes 0-499/1234" ) ,
382- Some ( ContentRange {
383- start: 0 ,
384- end: 499 ,
385- total: 1234
386- } )
387- ) ;
299+ let cr = ContentRange {
300+ start : 0 ,
301+ end : 499 ,
302+ total : 1234 ,
303+ } ;
304+ assert_eq ! ( cr. to_header_value( ) , "bytes 0-499/1234" ) ;
305+ assert_eq ! ( ContentRange :: parse( "bytes 0-499/1234" ) , Some ( cr) ) ;
388306 assert_eq ! ( ContentRange :: parse( "bytes */1234" ) , None ) ;
389307 assert_eq ! ( ContentRange :: parse( "invalid" ) , None ) ;
390308 }
391309
392310 #[ test]
393- fn content_range_parse_unsatisfiable_total ( ) {
311+ fn parse_unsatisfiable_total ( ) {
394312 assert_eq ! (
395313 ContentRange :: parse_unsatisfiable_total( "bytes */1234" ) ,
396314 Some ( 1234 )
0 commit comments