use std::fmt::{Formatter, Display, Result};
use hyper::error::{self, Error};
use hyper::header::{HeaderFormat, Header};
use {FieldMap};
const NT_HEADER_NAME: &'static str = "NT";
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct NT(pub FieldMap);
impl NT {
pub fn new(field: FieldMap) -> NT {
NT(field)
}
}
unsafe impl Sync for NT { }
unsafe impl Send for NT { }
impl Header for NT {
fn header_name() -> &'static str {
NT_HEADER_NAME
}
fn parse_header(raw: &[Vec<u8>]) -> error::Result<Self> {
if raw.len() != 1 {
return Err(Error::Header)
}
match FieldMap::new(&raw[0][..]) {
Some(n) => Ok(NT(n)),
None => Err(Error::Header)
}
}
}
impl HeaderFormat for NT {
fn fmt_header(&self, fmt: &mut Formatter) -> Result {
try!(Display::fmt(&self.0, fmt));
Ok(())
}
}
#[cfg(test)]
mod tests {
use hyper::header::{Header};
use super::{NT};
use FieldMap::{UPnP, UUID, URN, Unknown};
#[test]
fn positive_uuid() {
let uuid_header = &["uuid:a984bc8c-aaf0-5dff-b980-00d098bda247".to_string().into_bytes()];
let data = match NT::parse_header(uuid_header) {
Ok(NT(UUID(n))) => n,
_ => panic!("uuid Token Not Parsed")
};
assert!(uuid_header[0][5..].iter().zip(data.iter()).all(|(a,b)| a == b));
}
#[test]
fn positive_upnp() {
let upnp_header = &["upnp:rootdevice".to_string().into_bytes()];
let data = match NT::parse_header(upnp_header) {
Ok(NT(UPnP(n))) => n,
_ => panic!("upnp Token Not Parsed")
};
assert!(upnp_header[0][5..].iter().zip(data.iter()).all(|(a,b)| a == b));
}
#[test]
fn positive_urn() {
let urn_header = &["urn:schemas-upnp-org:device:printer:1".to_string().into_bytes()];
let data = match NT::parse_header(urn_header) {
Ok(NT(URN(n))) => n,
_ => panic!("urn Token Not Parsed")
};
assert!(urn_header[0][4..].iter().zip(data.iter()).all(|(a,b)| a == b));
}
#[test]
fn positive_unknown() {
let unknown_header = &["max-age:1500::upnp:rootdevice".to_string().into_bytes()];
let (k, v) = match NT::parse_header(unknown_header) {
Ok(NT(Unknown(k, v))) => (k, v),
_ => panic!("Unknown Token Not Parsed")
};
let sep_iter = b":".iter();
let mut original_iter = unknown_header[0][..].iter();
let mut result_iter = k[..].iter().chain(sep_iter).chain(v[..].iter());
assert!(original_iter.by_ref().zip(result_iter.by_ref()).all(|(&a,&b)| a == b));
assert!(result_iter.next().is_none() && original_iter.next().is_none());
}
#[test]
fn positive_short_field() {
let short_header = &["a:a".to_string().into_bytes()];
let (k, v) = match NT::parse_header(short_header) {
Ok(NT(Unknown(k, v))) => (k, v),
_ => panic!("Unknown Short Token Not Parsed")
};
let sep_iter = b":".iter();
let mut original_iter = short_header[0][..].iter();
let mut result_iter = k[..].iter().chain(sep_iter).chain(v[..].iter());
assert!(original_iter.by_ref().zip(result_iter.by_ref()).all(|(&a,&b)| a == b));
assert!(result_iter.next().is_none() && original_iter.next().is_none());
}
#[test]
fn positive_leading_double_colon() {
let leading_double_colon_header = &["uuid::a984bc8c-aaf0-5dff-b980-00d098bda247".to_string().into_bytes()];
let result = match NT::parse_header(leading_double_colon_header).unwrap() {
NT(UUID(n)) => n,
_ => panic!("NT Double Colon Failed To Parse")
};
assert_eq!(result, b":a984bc8c-aaf0-5dff-b980-00d098bda247".to_vec());
}
#[test]
#[should_panic]
fn negative_double_colon() {
let double_colon_header = &["::".to_string().into_bytes()];
NT::parse_header(double_colon_header).unwrap();
}
#[test]
#[should_panic]
fn negative_single_colon() {
let single_colon_header = &[":".to_string().into_bytes()];
NT::parse_header(single_colon_header).unwrap();
}
#[test]
#[should_panic]
fn negative_empty_field() {
let empty_header = &["".to_string().into_bytes()];
NT::parse_header(empty_header).unwrap();
}
#[test]
#[should_panic]
fn negative_no_colon() {
let no_colon_header = &["some_key-some_value".to_string().into_bytes()];
NT::parse_header(no_colon_header).unwrap();
}
}