range_header/byte_range.rs
1//! reference: <https://tools.ietf.org/html/rfc7233>
2
3use pest::Parser;
4use pest_derive::Parser;
5
6#[derive(Parser)]
7#[grammar = "./byte_range.pest"]
8struct ByteRangeParser;
9
10#[derive(Debug, Eq, PartialEq, Clone, Hash)]
11pub enum ByteRange {
12 FromTo(u64),
13 FromToAll(u64, u64),
14 Last(u64),
15}
16
17impl ByteRange {
18 /// Parses Range HTTP header string as per RFC 2733,but `bytes` only.
19 /// With invalid input, return empty vector
20 ///
21 /// # Examples
22 ///
23 /// ```rust
24 /// use range_header::ByteRange;
25 /// assert_eq!(
26 /// ByteRange::parse("bytes=10-100"),
27 /// vec![ByteRange::FromToAll(10, 100)]
28 /// );
29 ///
30 /// assert_eq!(
31 /// ByteRange::parse("bytes=10-"),
32 /// vec![ByteRange::FromTo(10)]
33 /// );
34 ///
35 ///assert_eq!(
36 /// ByteRange::parse("bytes=-100"),
37 /// vec![ByteRange::Last(100)]
38 /// );
39 ///
40 /// assert_eq!(
41 /// ByteRange::parse("invalid input"),
42 /// vec![]
43 /// );
44 /// ```
45 pub fn parse(header: &str) -> Vec<Self> {
46 let byte_range_spec_iter = match ByteRangeParser::parse(Rule::byte_ranges_specifier, header)
47 {
48 Err(_) => {
49 return vec![];
50 }
51 Ok(x) => x.peek().unwrap().into_inner(),
52 };
53
54 let mut result = Vec::new();
55 for spec in byte_range_spec_iter {
56 match spec.as_rule() {
57 Rule::from_to => {
58 // eg. '200-'
59 let offset: u64 = spec.into_inner().peek().unwrap().as_str().parse().unwrap();
60 result.push(ByteRange::FromTo(offset));
61 }
62 Rule::from_to_all => {
63 // eg, '200-300'
64 let mut inner_pairs = spec.into_inner();
65 let begin: u64 = inner_pairs.next().unwrap().as_str().parse().unwrap();
66 let end: u64 = inner_pairs.next().unwrap().as_str().parse().unwrap();
67
68 if begin > end {
69 continue;
70 }
71 result.push(ByteRange::FromToAll(begin, end));
72 }
73 Rule::last => {
74 // eg. '-200'
75 let length: u64 = spec.into_inner().peek().unwrap().as_str().parse().unwrap();
76 result.push(ByteRange::Last(length));
77 }
78 Rule::EOI => {}
79 _ => unreachable!(),
80 }
81 }
82 result
83 }
84}