darpi_headers/
accept_encoding.rs

1use crate::EncodingType;
2use std::cmp;
3use std::str::FromStr;
4
5pub struct AcceptEncoding {
6    pub encoding: EncodingType,
7    pub quality: f64,
8}
9
10impl Eq for AcceptEncoding {}
11
12impl Ord for AcceptEncoding {
13    #[allow(clippy::comparison_chain)]
14    fn cmp(&self, other: &AcceptEncoding) -> cmp::Ordering {
15        if self.quality > other.quality {
16            cmp::Ordering::Less
17        } else if self.quality < other.quality {
18            cmp::Ordering::Greater
19        } else {
20            cmp::Ordering::Equal
21        }
22    }
23}
24
25impl PartialOrd for AcceptEncoding {
26    fn partial_cmp(&self, other: &AcceptEncoding) -> Option<cmp::Ordering> {
27        Some(self.cmp(other))
28    }
29}
30
31impl PartialEq for AcceptEncoding {
32    fn eq(&self, other: &AcceptEncoding) -> bool {
33        self.quality == other.quality
34    }
35}
36
37impl AcceptEncoding {
38    fn new(tag: &str) -> Option<AcceptEncoding> {
39        let parts: Vec<&str> = tag.split(';').collect();
40        let encoding = match parts.len() {
41            0 => return None,
42            _ => EncodingType::from(parts[0]),
43        };
44        let quality = match parts.len() {
45            1 => encoding.quality(),
46            _ => match f64::from_str(parts[1]) {
47                Ok(q) => q,
48                Err(_) => 0.0,
49            },
50        };
51        Some(AcceptEncoding { encoding, quality })
52    }
53
54    /// Parse a raw Accept-Encoding header value into an ordered list.
55    pub fn parse(raw: &str, encoding: EncodingType) -> AcceptEncoding {
56        let mut encodings: Vec<Option<AcceptEncoding>> = raw
57            .replace(' ', "")
58            .split(',')
59            .map(|l| AcceptEncoding::new(l))
60            .collect();
61
62        encodings.sort();
63
64        for enc in encodings {
65            if let Some(enc) = enc {
66                if encoding == enc.encoding || encoding == EncodingType::Auto {
67                    return enc;
68                }
69            }
70        }
71        AcceptEncoding {
72            encoding: EncodingType::Identity,
73            quality: 0.0,
74        }
75    }
76}