Merge pull request #250 from pyfisch/headermacro2

refactor(headers): add header macros and add two example uses
This commit is contained in:
Sean McArthur
2015-01-15 10:56:14 -08:00
3 changed files with 66 additions and 41 deletions

View File

@@ -1,7 +1,4 @@
use std::fmt; use header::{self, shared};
use header;
use header::shared;
/// The `Accept-Encoding` header /// The `Accept-Encoding` header
/// ///
@@ -10,23 +7,9 @@ use header::shared;
#[derive(Clone, PartialEq, Show)] #[derive(Clone, PartialEq, Show)]
pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>); pub struct AcceptEncoding(pub Vec<shared::QualityItem<shared::Encoding>>);
deref!(AcceptEncoding => Vec<shared::QualityItem<shared::Encoding>>); impl_list_header!(AcceptEncoding,
"Accept-Encoding",
impl header::Header for AcceptEncoding { Vec<shared::QualityItem<shared::Encoding>>);
fn header_name(_: Option<AcceptEncoding>) -> &'static str {
"AcceptEncoding"
}
fn parse_header(raw: &[Vec<u8>]) -> Option<AcceptEncoding> {
shared::from_comma_delimited(raw).map(AcceptEncoding)
}
}
impl header::HeaderFormat for AcceptEncoding {
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
shared::fmt_comma_delimited(fmt, &self[])
}
}
#[test] #[test]
fn test_parse_header() { fn test_parse_header() {

View File

@@ -76,6 +76,64 @@ macro_rules! deref(
} }
); );
macro_rules! impl_list_header(
($from:ident, $name:expr, $item:ty) => {
deref!($from => $item);
impl header::Header for $from {
fn header_name(_: Option<$from>) -> &'static str {
$name
}
fn parse_header(raw: &[Vec<u8>]) -> Option<$from> {
$crate::header::shared::from_comma_delimited(raw).map($from)
}
}
impl header::HeaderFormat for $from {
fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
$crate::header::shared::fmt_comma_delimited(fmt, &self[])
}
}
impl ::std::fmt::String for $from {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use header::HeaderFormat;
self.fmt_header(f)
}
}
}
);
macro_rules! impl_header(
($from:ident, $name:expr, $item:ty) => {
deref!($from => $item);
impl header::Header for $from {
fn header_name(_: Option<$from>) -> &'static str {
$name
}
fn parse_header(raw: &[Vec<u8>]) -> Option<$from> {
$crate::header::shared::from_one_raw_str(raw).map($from)
}
}
impl header::HeaderFormat for $from {
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::String::fmt(&**self, f)
}
}
impl ::std::fmt::String for $from {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
use header::HeaderFormat;
self.fmt_header(f)
}
}
}
);
/// Exposes the AccessControl* family of headers. /// Exposes the AccessControl* family of headers.
pub mod access_control; pub mod access_control;

View File

@@ -1,6 +1,4 @@
use header::{Header, HeaderFormat}; use header;
use std::fmt;
use header::shared::util::from_one_raw_str;
/// The `Server` header field. /// The `Server` header field.
/// ///
@@ -8,22 +6,8 @@ use header::shared::util::from_one_raw_str;
#[derive(Clone, PartialEq, Show)] #[derive(Clone, PartialEq, Show)]
pub struct Server(pub String); pub struct Server(pub String);
deref!(Server => String); impl_header!(Server,
"Server",
impl Header for Server { String);
fn header_name(_: Option<Server>) -> &'static str {
"Server"
}
fn parse_header(raw: &[Vec<u8>]) -> Option<Server> {
from_one_raw_str(raw).map(|s| Server(s))
}
}
impl HeaderFormat for Server {
fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(&*self.0)
}
}
bench_header!(bench, Server, { vec![b"Some String".to_vec()] }); bench_header!(bench, Server, { vec![b"Some String".to_vec()] });