use crate::EncodingType;
use std::cmp;
use std::str::FromStr;
pub struct AcceptEncoding {
pub encoding: EncodingType,
pub quality: f64,
}
impl Eq for AcceptEncoding {}
impl Ord for AcceptEncoding {
#[allow(clippy::comparison_chain)]
fn cmp(&self, other: &AcceptEncoding) -> cmp::Ordering {
if self.quality > other.quality {
cmp::Ordering::Less
} else if self.quality < other.quality {
cmp::Ordering::Greater
} else {
cmp::Ordering::Equal
}
}
}
impl PartialOrd for AcceptEncoding {
fn partial_cmp(&self, other: &AcceptEncoding) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for AcceptEncoding {
fn eq(&self, other: &AcceptEncoding) -> bool {
self.quality == other.quality
}
}
impl AcceptEncoding {
fn new(tag: &str) -> Option<AcceptEncoding> {
let parts: Vec<&str> = tag.split(';').collect();
let encoding = match parts.len() {
0 => return None,
_ => EncodingType::from(parts[0]),
};
let quality = match parts.len() {
1 => encoding.quality(),
_ => match f64::from_str(parts[1]) {
Ok(q) => q,
Err(_) => 0.0,
},
};
Some(AcceptEncoding { encoding, quality })
}
pub fn parse(raw: &str, encoding: EncodingType) -> AcceptEncoding {
let mut encodings: Vec<Option<AcceptEncoding>> = raw
.replace(' ', "")
.split(',')
.map(|l| AcceptEncoding::new(l))
.collect();
encodings.sort();
for enc in encodings {
if let Some(enc) = enc {
if encoding == enc.encoding || encoding == EncodingType::Auto {
return enc;
}
}
}
AcceptEncoding {
encoding: EncodingType::Identity,
quality: 0.0,
}
}
}