feat(headers): header ergonomics

- Reexports all common::* as header::*
- Most headers implement Deref where it makes sense.

Closes #156
This commit is contained in:
Sean McArthur
2014-11-29 13:55:50 -08:00
parent 1014f63e15
commit 8071cfa8bf
18 changed files with 60 additions and 6 deletions

View File

@@ -134,7 +134,7 @@ impl Request<Fresh> {
match self.headers.get::<common::ContentLength>() { match self.headers.get::<common::ContentLength>() {
Some(cl) => { Some(cl) => {
chunked = false; chunked = false;
len = cl.len(); len = **cl;
}, },
None => () None => ()
}; };

View File

@@ -21,6 +21,8 @@ use mime::Mime;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Accept(pub Vec<Mime>); pub struct Accept(pub Vec<Mime>);
deref!(Accept -> Vec<Mime>)
impl Header for Accept { impl Header for Accept {
fn header_name(_: Option<Accept>) -> &'static str { fn header_name(_: Option<Accept>) -> &'static str {
"Accept" "Accept"

View File

@@ -7,6 +7,18 @@ use header::{Header, HeaderFormat};
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Authorization<S: Scheme>(pub S); pub struct Authorization<S: Scheme>(pub S);
impl<S: Scheme> Deref<S> for Authorization<S> {
fn deref<'a>(&'a self) -> &'a S {
&self.0
}
}
impl<S: Scheme> DerefMut<S> for Authorization<S> {
fn deref_mut<'a>(&'a mut self) -> &'a mut S {
&mut self.0
}
}
impl<S: Scheme> Header for Authorization<S> { impl<S: Scheme> Header for Authorization<S> {
fn header_name(_: Option<Authorization<S>>) -> &'static str { fn header_name(_: Option<Authorization<S>>) -> &'static str {
"Authorization" "Authorization"

View File

@@ -9,6 +9,8 @@ pub use self::ConnectionOption::{KeepAlive, Close, ConnectionHeader};
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Connection(pub Vec<ConnectionOption>); pub struct Connection(pub Vec<ConnectionOption>);
deref!(Connection -> Vec<ConnectionOption>)
/// Values that can be in the `Connection` header. /// Values that can be in the `Connection` header.
#[deriving(Clone, PartialEq)] #[deriving(Clone, PartialEq)]
pub enum ConnectionOption { pub enum ConnectionOption {

View File

@@ -9,6 +9,8 @@ use super::util::from_one_raw_str;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct ContentLength(pub uint); pub struct ContentLength(pub uint);
deref!(ContentLength -> uint)
impl Header for ContentLength { impl Header for ContentLength {
fn header_name(_: Option<ContentLength>) -> &'static str { fn header_name(_: Option<ContentLength>) -> &'static str {
"Content-Length" "Content-Length"
@@ -28,10 +30,10 @@ impl HeaderFormat for ContentLength {
impl ContentLength { impl ContentLength {
/// Returns the wrapped length. /// Returns the wrapped length.
#[deprecated = "use Deref instead"]
#[inline] #[inline]
pub fn len(&self) -> uint { pub fn len(&self) -> uint {
let ContentLength(len) = *self; **self
len
} }
} }

View File

@@ -10,6 +10,8 @@ use mime::Mime;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct ContentType(pub Mime); pub struct ContentType(pub Mime);
deref!(ContentType -> Mime)
impl Header for ContentType { impl Header for ContentType {
fn header_name(_: Option<ContentType>) -> &'static str { fn header_name(_: Option<ContentType>) -> &'static str {
"Content-Type" "Content-Type"

View File

@@ -16,6 +16,8 @@ use cookie::CookieJar;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Cookies(pub Vec<Cookie>); pub struct Cookies(pub Vec<Cookie>);
deref!(Cookies -> Vec<Cookie>)
impl Header for Cookies { impl Header for Cookies {
fn header_name(_: Option<Cookies>) -> &'static str { fn header_name(_: Option<Cookies>) -> &'static str {
"Cookie" "Cookie"

View File

@@ -9,6 +9,8 @@ use time::{Tm, strptime};
#[deriving(PartialEq, Clone)] #[deriving(PartialEq, Clone)]
pub struct Date(pub Tm); pub struct Date(pub Tm);
deref!(Date -> Tm)
impl Header for Date { impl Header for Date {
fn header_name(_: Option<Date>) -> &'static str { fn header_name(_: Option<Date>) -> &'static str {
"Date" "Date"

View File

@@ -16,6 +16,8 @@ use super::util::from_one_raw_str;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Location(pub String); pub struct Location(pub String);
deref!(Location -> String)
impl Header for Location { impl Header for Location {
fn header_name(_: Option<Location>) -> &'static str { fn header_name(_: Option<Location>) -> &'static str {
"Location" "Location"

View File

@@ -59,6 +59,22 @@ macro_rules! bench_header(
} }
) )
macro_rules! deref(
($from:ty -> $to:ty) => {
impl Deref<$to> for $from {
fn deref<'a>(&'a self) -> &'a $to {
&self.0
}
}
impl DerefMut<$to> for $from {
fn deref_mut<'a>(&'a mut self) -> &'a mut $to {
&mut self.0
}
}
}
)
/// Exposes the Accept header. /// Exposes the Accept header.
pub mod accept; pub mod accept;

View File

@@ -8,6 +8,8 @@ use super::util::from_one_raw_str;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Server(pub String); pub struct Server(pub String);
deref!(Server -> String)
impl Header for Server { impl Header for Server {
fn header_name(_: Option<Server>) -> &'static str { fn header_name(_: Option<Server>) -> &'static str {
"Server" "Server"

View File

@@ -13,6 +13,8 @@ use cookie::CookieJar;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct SetCookie(pub Vec<Cookie>); pub struct SetCookie(pub Vec<Cookie>);
deref!(SetCookie -> Vec<Cookie>)
impl Header for SetCookie { impl Header for SetCookie {
fn header_name(_: Option<SetCookie>) -> &'static str { fn header_name(_: Option<SetCookie>) -> &'static str {
"Set-Cookie" "Set-Cookie"

View File

@@ -21,6 +21,8 @@ use self::Encoding::{Chunked, Gzip, Deflate, Compress, EncodingExt};
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct TransferEncoding(pub Vec<Encoding>); pub struct TransferEncoding(pub Vec<Encoding>);
deref!(TransferEncoding -> Vec<Encoding>)
/// A value to be used with the `Transfer-Encoding` header. /// A value to be used with the `Transfer-Encoding` header.
/// ///
/// Example: /// Example:

View File

@@ -7,7 +7,9 @@ use self::Protocol::{WebSocket, ProtocolExt};
/// The `Upgrade` header. /// The `Upgrade` header.
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct Upgrade(Vec<Protocol>); pub struct Upgrade(pub Vec<Protocol>);
deref!(Upgrade -> Vec<Protocol>)
/// Protocol values that can appear in the Upgrade header. /// Protocol values that can appear in the Upgrade header.
#[deriving(Clone, PartialEq)] #[deriving(Clone, PartialEq)]

View File

@@ -8,6 +8,8 @@ use super::util::from_one_raw_str;
#[deriving(Clone, PartialEq, Show)] #[deriving(Clone, PartialEq, Show)]
pub struct UserAgent(pub String); pub struct UserAgent(pub String);
deref!(UserAgent -> String)
impl Header for UserAgent { impl Header for UserAgent {
fn header_name(_: Option<UserAgent>) -> &'static str { fn header_name(_: Option<UserAgent>) -> &'static str {
"User-Agent" "User-Agent"

View File

@@ -21,6 +21,8 @@ use uany::{UncheckedAnyDowncast, UncheckedAnyMutDowncast};
use http::{mod, LineEnding}; use http::{mod, LineEnding};
use {HttpResult}; use {HttpResult};
pub use self::common::*;
/// Common Headers /// Common Headers
pub mod common; pub mod common;

View File

@@ -1,5 +1,5 @@
#![feature(macro_rules, phase, default_type_params, if_let, slicing_syntax, #![feature(macro_rules, phase, default_type_params, if_let, slicing_syntax,
tuple_indexing)] tuple_indexing, globs)]
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(warnings)] #![deny(warnings)]
#![experimental] #![experimental]

View File

@@ -83,7 +83,7 @@ impl<'a> Response<'a, Fresh> {
match self.headers.get::<common::ContentLength>() { match self.headers.get::<common::ContentLength>() {
Some(cl) => { Some(cl) => {
chunked = false; chunked = false;
len = cl.len(); len = **cl;
}, },
None => () None => ()
}; };