#![feature(conservative_impl_trait)]
use std::ascii::AsciiExt;
pub fn transfer_encodings<'a>(s: &'a str) -> impl Iterator<Item = TransferEncoding<'a>> {
s.split(',').rev().map(TransferEncoding::new)
}
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum TransferEncoding<'a> {
Std(StdTransferEncoding),
Other(&'a str),
}
impl<'a> TransferEncoding<'a> {
pub fn new(s: &'a str) -> Self {
let s = s.trim();
match s.parse() {
Ok(enc) => TransferEncoding::Std(enc),
Err(_) => TransferEncoding::Other(s),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum StdTransferEncoding {
Chunked,
Compress,
Deflate,
Gzip,
}
impl std::str::FromStr for StdTransferEncoding {
type Err = ();
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
use self::StdTransferEncoding::*;
if s.eq_ignore_ascii_case("chunked") {
Ok(Chunked)
} else if s.eq_ignore_ascii_case("compress") {
Ok(Compress)
} else if s.eq_ignore_ascii_case("deflate") {
Ok(Deflate)
} else if s.eq_ignore_ascii_case("gzip") {
Ok(Gzip)
} else {
Err(())
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_te() {
use self::TransferEncoding::*;
use self::StdTransferEncoding::*;
assert_eq!(TransferEncoding::new("chunked"), Std(Chunked));
assert_eq!(TransferEncoding::new("chUNked"), Std(Chunked));
assert_eq!(TransferEncoding::new("chun ked"), Other("chun ked"));
assert_eq!(TransferEncoding::new(" chun\tked\t"), Other("chun\tked"));
assert_eq!(TransferEncoding::new("CHUNKED"), Std(Chunked));
assert_eq!(TransferEncoding::new(" CHUNKed "), Std(Chunked));
assert_eq!(TransferEncoding::new("compress"), Std(Compress));
assert_eq!(TransferEncoding::new(" cOMPress "), Std(Compress));
assert_eq!(TransferEncoding::new("deflate"), Std(Deflate));
assert_eq!(TransferEncoding::new("\n\r dEflAte \r"), Std(Deflate));
assert_eq!(TransferEncoding::new("gzip"), Std(Gzip));
assert_eq!(TransferEncoding::new(" GZiP\r\r\t"), Std(Gzip));
assert_eq!(TransferEncoding::new("\tgzIP "), Std(Gzip));
assert_eq!(TransferEncoding::new(""), Other(""));
assert_eq!(TransferEncoding::new(" \t "), Other(""));
assert_eq!(TransferEncoding::new("ÆØБД❤"), Other("ÆØБД❤"));
}
#[test]
fn test_tes() {
use self::TransferEncoding::*;
use self::StdTransferEncoding::*;
let mut te = transfer_encodings("chunked");
assert_eq!(te.next().unwrap(), Std(Chunked));
assert!(te.next().is_none());
let mut te = transfer_encodings("chunked, gzip, compress");
assert_eq!(te.next().unwrap(), Std(Compress));
assert_eq!(te.next().unwrap(), Std(Gzip));
assert_eq!(te.next().unwrap(), Std(Chunked));
assert!(te.next().is_none());
let mut te = transfer_encodings(" ChuNKEd ,\t\t gZIp\r\r, coMPRess\n\t , ,");
assert_eq!(te.next().unwrap(), Other(""));
assert_eq!(te.next().unwrap(), Other(""));
assert_eq!(te.next().unwrap(), Std(Compress));
assert_eq!(te.next().unwrap(), Std(Gzip));
assert_eq!(te.next().unwrap(), Std(Chunked));
assert!(te.next().is_none());
let mut te = transfer_encodings("\t\tdeflate,hello, UNknown\r\r");
assert_eq!(te.next().unwrap(), Other("UNknown"));
assert_eq!(te.next().unwrap(), Other("hello"));
assert_eq!(te.next().unwrap(), Std(Deflate));
assert!(te.next().is_none());
}
}