diff --git a/examples/headers.rs b/examples/headers.rs new file mode 100644 index 0000000000..65f943d870 --- /dev/null +++ b/examples/headers.rs @@ -0,0 +1,13 @@ +#![deny(warnings)] + +#[macro_use] +// TODO: only import header!, blocked by /~https://github.com/rust-lang/rust/issues/25003 +extern crate hyper; + +// A header in the form of `X-Foo: some random string` +header! { + (Foo, "X-Foo") => [String] +} + +fn main() { +} diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index fd60f930af..ddae1387e7 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -95,6 +95,21 @@ macro_rules! deref( } ); +macro_rules! tm { + ($id:ident, $tm:ident{$($tf:item)*}) => { + #[allow(unused_imports)] + mod $tm{ + use std::str; + use $crate::header::*; + use $crate::mime::*; + use $crate::method::Method; + use super::$id as HeaderField; + $($tf)* + } + + } +} + #[macro_export] macro_rules! test_header { ($id:ident, $raw:expr) => { @@ -135,7 +150,7 @@ macro_rules! header { // $nn:expr: Nice name of the header // List header, zero or more items - ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)* $tm:ident{$($tf:item)*}) => { + ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)*) => { $(#[$a])* #[derive(Clone, Debug, PartialEq)] pub struct $id(pub Vec<$item>); @@ -159,19 +174,9 @@ macro_rules! header { self.fmt_header(f) } } - #[allow(unused_imports)] - mod $tm{ - use std::str; - use $crate::header::*; - use $crate::mime::*; - use $crate::method::Method; - use super::$id as HeaderField; - $($tf)* - } - }; // List header, one or more items - ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)+ $tm:ident{$($tf:item)*}) => { + ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)+) => { $(#[$a])* #[derive(Clone, Debug, PartialEq)] pub struct $id(pub Vec<$item>); @@ -195,18 +200,9 @@ macro_rules! header { self.fmt_header(f) } } - #[allow(unused_imports)] - mod $tm{ - use std::str; - use $crate::header::*; - use $crate::mime::*; - use $crate::method::Method; - use super::$id as HeaderField; - $($tf)* - } }; // Single value header - ($(#[$a:meta])*($id:ident, $n:expr) => [$value:ty] $tm:ident{$($tf:item)*}) => { + ($(#[$a:meta])*($id:ident, $n:expr) => [$value:ty]) => { $(#[$a])* #[derive(Clone, Debug, PartialEq)] pub struct $id(pub $value); @@ -229,18 +225,9 @@ macro_rules! header { ::std::fmt::Display::fmt(&**self, f) } } - #[allow(unused_imports)] - mod $tm{ - use std::str; - use $crate::header::*; - use $crate::mime::*; - use $crate::method::Method; - use super::$id as HeaderField; - $($tf)* - } }; // List header, one or more items with "*" option - ($(#[$a:meta])*($id:ident, $n:expr) => {Any / ($item:ty)+} $tm:ident{$($tf:item)*}) => { + ($(#[$a:meta])*($id:ident, $n:expr) => {Any / ($item:ty)+}) => { $(#[$a])* #[derive(Clone, Debug, PartialEq)] pub enum $id { @@ -279,18 +266,44 @@ macro_rules! header { self.fmt_header(f) } } - #[allow(unused_imports)] - mod $tm{ - use std::str; - use $crate::header::*; - use $crate::mime::*; - use $crate::method::Method; - use super::$id as HeaderField; - $($tf)* + }; + + // optional test module + ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)* $tm:ident{$($tf:item)*}) => { + header! { + $(#[$a])* + ($id, $n) => ($item)* } + + tm! { $id, $tm { $($tf)* }} + }; + ($(#[$a:meta])*($id:ident, $n:expr) => ($item:ty)+ $tm:ident{$($tf:item)*}) => { + header! { + $(#[$a])* + ($id, $n) => ($item)+ + } + + tm! { $id, $tm { $($tf)* }} + }; + ($(#[$a:meta])*($id:ident, $n:expr) => [$item:ty] $tm:ident{$($tf:item)*}) => { + header! { + $(#[$a])* + ($id, $n) => [$item] + } + + tm! { $id, $tm { $($tf)* }} + }; + ($(#[$a:meta])*($id:ident, $n:expr) => {Any / ($item:ty)+} $tm:ident{$($tf:item)*}) => { + header! { + $(#[$a])* + ($id, $n) => {Any / ($item)+} + } + + tm! { $id, $tm { $($tf)* }} }; } + mod accept; mod access_control_allow_headers; mod access_control_allow_methods;