feat(langtags): use true language tags in headers
Make hyper dependant on rust-language-tags providing complete parsing and formatting of language tags. Remove builtin solution for simple tags. BREAKING CHANGE: AcceptLanguage and ContentLanguage use LanguageTag now, Language removed from Hyper.
This commit is contained in:
		| @@ -13,6 +13,7 @@ keywords = ["http", "hyper", "hyperium"] | ||||
|  | ||||
| [dependencies] | ||||
| httparse = "0.1" | ||||
| language-tags = "0.0.7" | ||||
| log = "0.3" | ||||
| mime = "0.0.12" | ||||
| num_cpus = "0.2" | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| use header::{Language, QualityItem}; | ||||
| use language_tags::LanguageTag; | ||||
| use header::QualityItem; | ||||
|  | ||||
| header! { | ||||
|     #[doc="`Accept-Language` header, defined in"] | ||||
| @@ -20,61 +21,47 @@ header! { | ||||
|     #[doc=""] | ||||
|     #[doc="# Examples"] | ||||
|     #[doc="```"] | ||||
|     #[doc="use hyper::header::{Headers, AcceptLanguage, Language, qitem};"] | ||||
|     #[doc="use hyper::LanguageTag;"] | ||||
|     #[doc="use hyper::header::{Headers, AcceptLanguage, qitem};"] | ||||
|     #[doc=""] | ||||
|     #[doc="let mut headers = Headers::new();"] | ||||
|     #[doc="let mut langtag: LanguageTag = Default::default();"] | ||||
|     #[doc="langtag.language = Some(\"en\".to_owned());"] | ||||
|     #[doc="langtag.region = Some(\"US\".to_owned());"] | ||||
|     #[doc="headers.set("] | ||||
|     #[doc="    AcceptLanguage(vec!["] | ||||
|     #[doc="        qitem("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                 primary: \"en\".to_owned(),"] | ||||
|     #[doc="                 sub: Some(\"us\".to_owned()),"] | ||||
|     #[doc="            }"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        qitem(langtag),"] | ||||
|     #[doc="    ])"] | ||||
|     #[doc=");"] | ||||
|     #[doc="```"] | ||||
|     #[doc="```"] | ||||
|     #[doc="use hyper::header::{Headers, AcceptLanguage, Language, QualityItem, Quality, qitem};"] | ||||
|     #[doc=""] | ||||
|     #[doc="# extern crate hyper;"] | ||||
|     #[doc="# #[macro_use] extern crate language_tags;"] | ||||
|     #[doc="# use hyper::header::{Headers, AcceptLanguage, QualityItem, Quality, qitem};"] | ||||
|     #[doc="# "] | ||||
|     #[doc="# fn main() {"] | ||||
|     #[doc="let mut headers = Headers::new();"] | ||||
|     #[doc="headers.set("] | ||||
|     #[doc="    AcceptLanguage(vec!["] | ||||
|     #[doc="        qitem("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                primary: \"da\".to_owned(),"] | ||||
|     #[doc="                sub: None,"] | ||||
|     #[doc="             }"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        QualityItem::new("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                primary: \"en\".to_owned(),"] | ||||
|     #[doc="                sub: Some(\"gb\".to_owned()),"] | ||||
|     #[doc="            },"] | ||||
|     #[doc="            Quality(800),"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        QualityItem::new("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                primary: \"en\".to_owned(),"] | ||||
|     #[doc="                sub: None,"] | ||||
|     #[doc="            },"] | ||||
|     #[doc="            Quality(700),"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        qitem(langtag!(da)),"] | ||||
|     #[doc="        QualityItem::new(langtag!(en;;;GB), Quality(800)),"] | ||||
|     #[doc="        QualityItem::new(langtag!(en), Quality(700)),"] | ||||
|     #[doc="    ])"] | ||||
|     #[doc=");"] | ||||
|     #[doc="# }"] | ||||
|     #[doc="```"] | ||||
|     (AcceptLanguage, "Accept-Language") => (QualityItem<Language>)+ | ||||
|     (AcceptLanguage, "Accept-Language") => (QualityItem<LanguageTag>)+ | ||||
|  | ||||
|     test_accept_language { | ||||
|         // From the RFC | ||||
|         test_header!(test1, vec![b"da, en-gb;q=0.8, en;q=0.7"]); | ||||
|         // Own test | ||||
|         test_header!( | ||||
|             test2, vec![b"en-us, en; q=0.5, fr"], | ||||
|             test2, vec![b"en-US, en; q=0.5, fr"], | ||||
|             Some(AcceptLanguage(vec![ | ||||
|                 qitem(Language {primary: "en".to_owned(), sub: Some("us".to_owned())}), | ||||
|                 QualityItem::new(Language{primary: "en".to_owned(), sub: None}, Quality(500)), | ||||
|                 qitem(Language {primary: "fr".to_owned(), sub: None}), | ||||
|                 qitem(langtag!(en;;;US)), | ||||
|                 QualityItem::new(langtag!(en), Quality(500)), | ||||
|                 qitem(langtag!(fr)), | ||||
|         ]))); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| use header::{Language, QualityItem}; | ||||
| use language_tags::LanguageTag; | ||||
| use header::QualityItem; | ||||
|  | ||||
| header! { | ||||
|     #[doc="`Content-Language` header, defined in"] | ||||
| @@ -20,42 +21,36 @@ header! { | ||||
|     #[doc=""] | ||||
|     #[doc="# Examples"] | ||||
|     #[doc="```"] | ||||
|     #[doc="use hyper::header::{Headers, ContentLanguage, Language, qitem};"] | ||||
|     #[doc="# extern crate hyper;"] | ||||
|     #[doc="# #[macro_use] extern crate language_tags;"] | ||||
|     #[doc="# use hyper::header::{Headers, ContentLanguage, qitem};"] | ||||
|     #[doc="# "] | ||||
|     #[doc="# fn main() {"] | ||||
|     #[doc="let mut headers = Headers::new();"] | ||||
|     #[doc="headers.set("] | ||||
|     #[doc="    ContentLanguage(vec!["] | ||||
|     #[doc="        qitem(langtag!(en)),"] | ||||
|     #[doc="    ])"] | ||||
|     #[doc=");"] | ||||
|     #[doc="# }"] | ||||
|     #[doc="```"] | ||||
|     #[doc="```"] | ||||
|     #[doc="# extern crate hyper;"] | ||||
|     #[doc="# #[macro_use] extern crate language_tags;"] | ||||
|     #[doc="# use hyper::header::{Headers, ContentLanguage, qitem};"] | ||||
|     #[doc="# "] | ||||
|     #[doc="# fn main() {"] | ||||
|     #[doc=""] | ||||
|     #[doc="let mut headers = Headers::new();"] | ||||
|     #[doc="headers.set("] | ||||
|     #[doc="    ContentLanguage(vec!["] | ||||
|     #[doc="        qitem("] | ||||
|     #[doc="            Language { "] | ||||
|     #[doc="                 primary: \"en\".to_owned(),"] | ||||
|     #[doc="                 sub: None,"] | ||||
|     #[doc="            }"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        qitem(langtag!(da)),"] | ||||
|     #[doc="        qitem(langtag!(en;;;GB)),"] | ||||
|     #[doc="    ])"] | ||||
|     #[doc=");"] | ||||
|     #[doc="# }"] | ||||
|     #[doc="```"] | ||||
|     #[doc="```"] | ||||
|     #[doc="use hyper::header::{Headers, ContentLanguage, Language, qitem};"] | ||||
|     #[doc=""] | ||||
|     #[doc="let mut headers = Headers::new();"] | ||||
|     #[doc="headers.set("] | ||||
|     #[doc="    ContentLanguage(vec!["] | ||||
|     #[doc="        qitem("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                primary: \"da\".to_owned(),"] | ||||
|     #[doc="                sub: None,"] | ||||
|     #[doc="             }"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="        qitem("] | ||||
|     #[doc="            Language {"] | ||||
|     #[doc="                primary: \"en\".to_owned(),"] | ||||
|     #[doc="                sub: Some(\"gb\".to_owned()),"] | ||||
|     #[doc="            }"] | ||||
|     #[doc="        ),"] | ||||
|     #[doc="    ])"] | ||||
|     #[doc=");"] | ||||
|     #[doc="```"] | ||||
|     (ContentLanguage, "Content-Language") => (QualityItem<Language>)+ | ||||
|     (ContentLanguage, "Content-Language") => (QualityItem<LanguageTag>)+ | ||||
|  | ||||
|     test_content_language { | ||||
|         test_header!(test1, vec![b"da"]); | ||||
|   | ||||
| @@ -103,10 +103,12 @@ macro_rules! __hyper__deref { | ||||
| macro_rules! __hyper__tm { | ||||
|     ($id:ident, $tm:ident{$($tf:item)*}) => { | ||||
|         #[allow(unused_imports)] | ||||
|         #[cfg(test)] | ||||
|         mod $tm{ | ||||
|             use std::str; | ||||
|             use $crate::header::*; | ||||
|             use $crate::mime::*; | ||||
|             use $crate::language_tags::*; | ||||
|             use $crate::method::Method; | ||||
|             use super::$id as HeaderField; | ||||
|             $($tf)* | ||||
|   | ||||
| @@ -1,45 +0,0 @@ | ||||
| use std::str::FromStr; | ||||
| use std::fmt; | ||||
|  | ||||
| /// A language tag. | ||||
| /// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.10 | ||||
| /// | ||||
| /// Note: This is no complete language tag implementation, it should be replaced with | ||||
| /// github.com/pyfisch/rust-language-tag once it is ready. | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct Language { | ||||
|     /// The language tag | ||||
|     pub primary: String, | ||||
|     /// A language subtag or country code | ||||
|     pub sub: Option<String> | ||||
| } | ||||
|  | ||||
| impl FromStr for Language { | ||||
|     type Err = ::Error; | ||||
|     fn from_str(s: &str) -> ::Result<Language> { | ||||
|         let mut i = s.split("-"); | ||||
|         let p = i.next(); | ||||
|         let s = i.next(); | ||||
|         match (p, s) { | ||||
|             (Some(p), Some(s)) => Ok(Language { | ||||
|                 primary: p.to_owned(), | ||||
|                 sub: Some(s.to_owned()) | ||||
|                 }), | ||||
|             (Some(p), _) => Ok(Language { | ||||
|                 primary: p.to_owned(), | ||||
|                 sub: None | ||||
|                 }), | ||||
|             _ => Err(::Error::Header) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for Language { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         try!(f.write_str(&self.primary[..])); | ||||
|         match self.sub { | ||||
|             Some(ref s) => write!(f, "-{}", s), | ||||
|             None => Ok(()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -2,12 +2,10 @@ pub use self::charset::Charset; | ||||
| pub use self::encoding::Encoding; | ||||
| pub use self::entity::EntityTag; | ||||
| pub use self::httpdate::HttpDate; | ||||
| pub use self::language::Language; | ||||
| pub use self::quality_item::{Quality, QualityItem, qitem, q}; | ||||
|  | ||||
| mod charset; | ||||
| mod encoding; | ||||
| mod entity; | ||||
| mod httpdate; | ||||
| mod language; | ||||
| mod quality_item; | ||||
|   | ||||
| @@ -141,6 +141,9 @@ extern crate traitobject; | ||||
| extern crate typeable; | ||||
| extern crate solicit; | ||||
|  | ||||
| #[macro_use] | ||||
| extern crate language_tags; | ||||
|  | ||||
| #[macro_use] | ||||
| extern crate mime as mime_crate; | ||||
|  | ||||
| @@ -157,6 +160,7 @@ pub use error::{Result, Error}; | ||||
| pub use method::Method::{Get, Head, Post, Delete}; | ||||
| pub use status::StatusCode::{Ok, BadRequest, NotFound}; | ||||
| pub use server::Server; | ||||
| pub use language_tags::LanguageTag; | ||||
|  | ||||
| macro_rules! todo( | ||||
|     ($($arg:tt)*) => (if cfg!(not(ndebug)) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user