darpi_headers/
accept_encoding.rs1use 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 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}