feat(headers): add AcceptLanguage header
Adds header support for Accept-Language, using a struct for the primary and sub components of the language.
This commit is contained in:
		
							
								
								
									
										86
									
								
								src/header/common/accept_language.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/header/common/accept_language.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | use header::{self, QualityItem}; | ||||||
|  | use std::str::FromStr; | ||||||
|  | use std::fmt; | ||||||
|  |  | ||||||
|  | /// A language tag. | ||||||
|  | /// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.10 | ||||||
|  | #[derive(Clone, PartialEq, Debug)] | ||||||
|  | pub struct Language{ | ||||||
|  |     primary: String, | ||||||
|  |     sub: Option<String> | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl FromStr for Language { | ||||||
|  |     type Err = (); | ||||||
|  |     fn from_str(s: &str) -> Result<Language, ()> { | ||||||
|  |         let mut i = s.split_str("-"); | ||||||
|  |         let p = i.next(); | ||||||
|  |         let s = i.next(); | ||||||
|  |         match (p, s) { | ||||||
|  |             (Some(p),Some(s)) => Ok(Language{primary: p.to_string(), | ||||||
|  |                                              sub: Some(s.to_string())}), | ||||||
|  |             (Some(p),_) => Ok(Language{primary: p.to_string(), sub: None}), | ||||||
|  |             _ => Err(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl fmt::Display for Language { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         try!(write!(f, "{}", self.primary)); | ||||||
|  |         match self.sub { | ||||||
|  |             Some(ref s) => write!(f, "-{}", s), | ||||||
|  |             None => Ok(()) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// The `Accept-Language` header | ||||||
|  | /// | ||||||
|  | /// The `Accept-Language` header can be used by clients to indicate what | ||||||
|  | /// response languages they accept. | ||||||
|  | #[derive(Clone, PartialEq, Debug)] | ||||||
|  | pub struct AcceptLanguage(pub Vec<QualityItem<Language>>); | ||||||
|  |  | ||||||
|  | impl_list_header!(AcceptLanguage, | ||||||
|  |                   "Accept-Language", | ||||||
|  |                   Vec<QualityItem<Language>>); | ||||||
|  |  | ||||||
|  | bench_header!(bench, AcceptLanguage, | ||||||
|  |               { vec![b"en-us;q=1.0, en;q=0.5, fr".to_vec()] }); | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_parse_header() { | ||||||
|  |     let a: AcceptLanguage = header::Header::parse_header( | ||||||
|  |         [b"en-us;q=1.0, en;q=0.5, fr".to_vec()].as_slice()).unwrap(); | ||||||
|  |     let b = AcceptLanguage(vec![ | ||||||
|  |         QualityItem { item: Language{primary: "en".to_string(), | ||||||
|  |                                    sub: Some("us".to_string())}, | ||||||
|  |                       quality: 1f32 }, | ||||||
|  |         QualityItem { item: Language{primary: "en".to_string(), sub: None}, | ||||||
|  |                       quality: 0.5f32 }, | ||||||
|  |         QualityItem { item: Language{primary: "fr".to_string(), sub: None}, | ||||||
|  |                       quality: 1f32 }, | ||||||
|  |     ]); | ||||||
|  |     assert_eq!(format!("{}", a), format!("{}", b)); | ||||||
|  |     assert_eq!(a, b); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_display() { | ||||||
|  |     assert_eq!("en".to_string(), | ||||||
|  |                format!("{}", Language{primary: "en".to_string(), | ||||||
|  |                                       sub: None})); | ||||||
|  |     assert_eq!("en-us".to_string(), | ||||||
|  |                format!("{}", Language{primary: "en".to_string(), | ||||||
|  |                                       sub: Some("us".to_string())})); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_from_str() { | ||||||
|  |     assert_eq!(Language { primary: "en".to_string(), sub: None }, | ||||||
|  |                "en".parse().unwrap()); | ||||||
|  |     assert_eq!(Language { primary: "en".to_string(), | ||||||
|  |                           sub: Some("us".to_string()) }, | ||||||
|  |                "en-us".parse().unwrap()); | ||||||
|  | } | ||||||
| @@ -9,6 +9,7 @@ | |||||||
| pub use self::access_control::*; | pub use self::access_control::*; | ||||||
| pub use self::accept::Accept; | pub use self::accept::Accept; | ||||||
| pub use self::accept_encoding::AcceptEncoding; | pub use self::accept_encoding::AcceptEncoding; | ||||||
|  | pub use self::accept_language::AcceptLanguage; | ||||||
| pub use self::allow::Allow; | pub use self::allow::Allow; | ||||||
| pub use self::authorization::{Authorization, Scheme, Basic}; | pub use self::authorization::{Authorization, Scheme, Basic}; | ||||||
| pub use self::cache_control::{CacheControl, CacheDirective}; | pub use self::cache_control::{CacheControl, CacheDirective}; | ||||||
| @@ -147,6 +148,7 @@ macro_rules! impl_header( | |||||||
| mod access_control; | mod access_control; | ||||||
| mod accept; | mod accept; | ||||||
| mod accept_encoding; | mod accept_encoding; | ||||||
|  | mod accept_language; | ||||||
| mod allow; | mod allow; | ||||||
| mod authorization; | mod authorization; | ||||||
| mod cache_control; | mod cache_control; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user