Created
July 21, 2016 20:00
-
-
Save lily-mara/596d7a87636c44338724bc15e6939aa9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // From https://github.com/tailhook/quick-error | |
| #[macro_export] | |
| macro_rules! quick_error { | |
| ( $(#[$meta:meta])* | |
| pub enum $name:ident { $($chunks:tt)* } | |
| ) => { | |
| quick_error!(SORT [pub enum $name $(#[$meta])* ] | |
| items [] buf [] | |
| queue [ $($chunks)* ]); | |
| }; | |
| ( $(#[$meta:meta])* | |
| enum $name:ident { $($chunks:tt)* } | |
| ) => { | |
| quick_error!(SORT [enum $name $(#[$meta])* ] | |
| items [] buf [] | |
| queue [ $($chunks)* ]); | |
| }; | |
| // Queue is empty, can do the work | |
| (SORT [enum $name:ident $( #[$meta:meta] )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [ ] | |
| queue [ ] | |
| ) => { | |
| quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*] | |
| body [] | |
| queue [$($( #[$imeta] )* | |
| => $iitem: $imode [$( $ivar: $ityp ),*] )*] | |
| ); | |
| quick_error!(IMPLEMENTATIONS $name {$( | |
| $iitem: $imode [$( $ivar: $ityp ),*] {$( $ifuncs )*} | |
| )*}); | |
| $( | |
| quick_error!(ERROR_CHECK $imode $($ifuncs)*); | |
| )* | |
| }; | |
| (SORT [pub enum $name:ident $( #[$meta:meta] )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [ ] | |
| queue [ ] | |
| ) => { | |
| quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*] | |
| body [] | |
| queue [$($( #[$imeta] )* | |
| => $iitem: $imode [$( $ivar: $ityp ),*] )*] | |
| ); | |
| quick_error!(IMPLEMENTATIONS $name {$( | |
| $iitem: $imode [$( $ivar: $ityp ),*] {$( $ifuncs )*} | |
| )*}); | |
| $( | |
| quick_error!(ERROR_CHECK $imode $($ifuncs)*); | |
| )* | |
| }; | |
| // Add meta to buffer | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )*] | |
| queue [ #[$qmeta:meta] $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] | |
| buf [$( #[$bmeta] )* #[$qmeta] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Add ident to buffer | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )*] | |
| queue [ $qitem:ident $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* | |
| => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] | |
| buf [$(#[$bmeta])* => $qitem : UNIT [ ] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Flush buffer on meta after ident | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* | |
| => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] | |
| queue [ #[$qmeta:meta] $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* | |
| $(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* | |
| $bitem: $bmode [$( $bvar:$btyp ),*] {} ] | |
| buf [ #[$qmeta] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Add tuple enum-variant | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] | |
| queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] | |
| buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),*] ] | |
| queue [$( $tail )*] | |
| ); | |
| }; | |
| // Add struct enum-variant - e.g. { descr: &'static str } | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] | |
| queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] | |
| buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Add struct enum-variant, with excess comma - e.g. { descr: &'static str, } | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ] | |
| queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*] | |
| buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),*] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Add braces and flush always on braces | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* | |
| => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] | |
| queue [ {$( $qfuncs:tt )*} $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* | |
| $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ] | |
| buf [ ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Flush buffer on double ident | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* | |
| => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] | |
| queue [ $qitem:ident $( $tail:tt )*] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* | |
| $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ] | |
| buf [ => $qitem : UNIT [ ] ] | |
| queue [$( $tail )*]); | |
| }; | |
| // Flush buffer on end | |
| (SORT [$( $def:tt )*] | |
| items [$($( #[$imeta:meta] )* | |
| => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] | |
| {$( $ifuncs:tt )*} )* ] | |
| buf [$( #[$bmeta:meta] )* | |
| => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ] | |
| queue [ ] | |
| ) => { | |
| quick_error!(SORT [$( $def )*] | |
| items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )* | |
| $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ] | |
| buf [ ] | |
| queue [ ]); | |
| }; | |
| // Public enum (Queue Empty) | |
| (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*] | |
| body [$($( #[$imeta:meta] )* | |
| => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] | |
| queue [ ] | |
| ) => { | |
| $(#[$meta])* | |
| pub enum $name { | |
| $( | |
| $(#[$imeta])* | |
| $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*, | |
| )* | |
| } | |
| }; | |
| // Private enum (Queue Empty) | |
| (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*] | |
| body [$($( #[$imeta:meta] )* | |
| => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] | |
| queue [ ] | |
| ) => { | |
| $(#[$meta])* | |
| enum $name { | |
| $( | |
| $(#[$imeta])* | |
| $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*, | |
| )* | |
| } | |
| }; | |
| // Unit variant | |
| (ENUM_DEFINITION [$( $def:tt )*] | |
| body [$($( #[$imeta:meta] )* | |
| => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] | |
| queue [$( #[$qmeta:meta] )* | |
| => $qitem:ident: UNIT [ ] $( $queue:tt )*] | |
| ) => { | |
| quick_error!(ENUM_DEFINITION [ $($def)* ] | |
| body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* | |
| $( #[$qmeta] )* => $qitem () {} ] | |
| queue [ $($queue)* ] | |
| ); | |
| }; | |
| // Tuple variant | |
| (ENUM_DEFINITION [$( $def:tt )*] | |
| body [$($( #[$imeta:meta] )* | |
| => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] | |
| queue [$( #[$qmeta:meta] )* | |
| => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*] | |
| ) => { | |
| quick_error!(ENUM_DEFINITION [ $($def)* ] | |
| body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* | |
| $( #[$qmeta] )* => $qitem (($( $qtyp ),*)) {} ] | |
| queue [ $($queue)* ] | |
| ); | |
| }; | |
| // Struct variant | |
| (ENUM_DEFINITION [$( $def:tt )*] | |
| body [$($( #[$imeta:meta] )* | |
| => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] | |
| queue [$( #[$qmeta:meta] )* | |
| => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*] | |
| ) => { | |
| quick_error!(ENUM_DEFINITION [ $($def)* ] | |
| body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )* | |
| $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ] | |
| queue [ $($queue)* ] | |
| ); | |
| }; | |
| (IMPLEMENTATIONS | |
| $name:ident {$( | |
| $item:ident: $imode:tt [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*} | |
| )*} | |
| ) => { | |
| #[allow(unused)] | |
| impl ::std::fmt::Display for $name { | |
| fn fmt(&self, fmt: &mut ::std::fmt::Formatter) | |
| -> ::std::fmt::Result | |
| { | |
| match *self { | |
| $( | |
| quick_error!(ITEM_PATTERN | |
| $name $item: $imode [$( ref $var ),*] | |
| ) => { | |
| let display_fn = quick_error!(FIND_DISPLAY_IMPL | |
| $name $item: $imode | |
| {$( $funcs )*}); | |
| display_fn(self, fmt) | |
| } | |
| )* | |
| } | |
| } | |
| } | |
| // #[allow(unused)] | |
| // impl ::std::error::Error for $name { | |
| // fn description(&self) -> &str { | |
| // match *self { | |
| // $( | |
| // quick_error!(ITEM_PATTERN | |
| // $name $item: $imode [$( ref $var ),*] | |
| // ) => { | |
| // quick_error!(FIND_DESCRIPTION_IMPL | |
| // $item: $imode self fmt [$( $var ),*] | |
| // {$( $funcs )*}) | |
| // } | |
| // )* | |
| // } | |
| // } | |
| // fn cause(&self) -> Option<&::std::error::Error> { | |
| // match *self { | |
| // $( | |
| // quick_error!(ITEM_PATTERN | |
| // $name $item: $imode [$( ref $var ),*] | |
| // ) => { | |
| // quick_error!(FIND_CAUSE_IMPL | |
| // $item: $imode [$( $var ),*] | |
| // {$( $funcs )*}) | |
| // } | |
| // )* | |
| // } | |
| // } | |
| // } | |
| #[allow(unused)] | |
| impl $name { | |
| pub fn description(&self) -> &str { | |
| match *self { | |
| $( | |
| quick_error!(ITEM_PATTERN | |
| $name $item: $imode [$( ref $var ),*] | |
| ) => { | |
| quick_error!(FIND_DESCRIPTION_IMPL | |
| $item: $imode self fmt [$( $var ),*] | |
| {$( $funcs )*}) | |
| } | |
| )* | |
| } | |
| } | |
| } | |
| $( | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: $imode [$( $var:$typ ),*] | |
| {$( $funcs )*}); | |
| )* | |
| }; | |
| (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt | |
| { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*} | |
| ) => { | |
| |quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| { write!(f, $( $exprs )*) } | |
| }; | |
| (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt | |
| { display($pattern:expr) $( $tail:tt )*} | |
| ) => { | |
| |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern) } | |
| }; | |
| (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt | |
| { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*} | |
| ) => { | |
| |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern, $( $exprs )*) } | |
| }; | |
| (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt | |
| { $t:tt $( $tail:tt )*} | |
| ) => { | |
| quick_error!(FIND_DISPLAY_IMPL | |
| $name $item: $imode | |
| {$( $tail )*}) | |
| }; | |
| (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt | |
| { } | |
| ) => { | |
| |self_: &$name, f: &mut ::std::fmt::Formatter| { | |
| write!(f, "{}", self_.description()) | |
| } | |
| }; | |
| (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident | |
| [$( $var:ident ),*] | |
| { description($expr:expr) $( $tail:tt )*} | |
| ) => { | |
| $expr | |
| }; | |
| (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident | |
| [$( $var:ident ),*] | |
| { $t:tt $( $tail:tt )*} | |
| ) => { | |
| quick_error!(FIND_DESCRIPTION_IMPL | |
| $item: $imode $me $fmt [$( $var ),*] | |
| {$( $tail )*}) | |
| }; | |
| (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident | |
| [$( $var:ident ),*] | |
| { } | |
| ) => { | |
| stringify!($item) | |
| }; | |
| (FIND_CAUSE_IMPL $item:ident: $imode:tt | |
| [$( $var:ident ),*] | |
| { cause($expr:expr) $( $tail:tt )*} | |
| ) => { | |
| Some($expr) | |
| }; | |
| (FIND_CAUSE_IMPL $item:ident: $imode:tt | |
| [$( $var:ident ),*] | |
| { $t:tt $( $tail:tt )*} | |
| ) => { | |
| quick_error!(FIND_CAUSE_IMPL | |
| $item: $imode [$( $var ),*] | |
| { $($tail)* }) | |
| }; | |
| (FIND_CAUSE_IMPL $item:ident: $imode:tt | |
| [$( $var:ident ),*] | |
| { } | |
| ) => { | |
| None | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt | |
| [$( $var:ident: $typ:ty ),*] | |
| { from() $( $tail:tt )*} | |
| ) => { | |
| $( | |
| impl From<$typ> for $name { | |
| fn from($var: $typ) -> $name { | |
| $name::$item($var) | |
| } | |
| } | |
| )* | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: $imode [$( $var:$typ ),*] | |
| {$( $tail )*}); | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: UNIT | |
| [ ] | |
| { from($ftyp:ty) $( $tail:tt )*} | |
| ) => { | |
| impl From<$ftyp> for $name { | |
| fn from(_discarded_error: $ftyp) -> $name { | |
| $name::$item | |
| } | |
| } | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: UNIT [ ] | |
| {$( $tail )*}); | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: TUPLE | |
| [$( $var:ident: $typ:ty ),*] | |
| { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*} | |
| ) => { | |
| impl From<$ftyp> for $name { | |
| fn from($fvar: $ftyp) -> $name { | |
| $name::$item($( $texpr ),*) | |
| } | |
| } | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: TUPLE [$( $var:$typ ),*] | |
| { $($tail)* }); | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: STRUCT | |
| [$( $var:ident: $typ:ty ),*] | |
| { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*} | |
| ) => { | |
| impl From<$ftyp> for $name { | |
| fn from($fvar: $ftyp) -> $name { | |
| $name::$item { | |
| $( $tvar: $texpr ),* | |
| } | |
| } | |
| } | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: STRUCT [$( $var:$typ ),*] | |
| { $($tail)* }); | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt | |
| [$( $var:ident: $typ:ty ),*] | |
| { $t:tt $( $tail:tt )*} | |
| ) => { | |
| quick_error!(FIND_FROM_IMPL | |
| $name $item: $imode [$( $var:$typ ),*] | |
| {$( $tail )*} | |
| ); | |
| }; | |
| (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt | |
| [$( $var:ident: $typ:ty ),*] | |
| { } | |
| ) => { | |
| }; | |
| (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT | |
| ) => { }; | |
| (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE | |
| [$( $typ:ty ),*] | |
| ) => { | |
| ($( $typ ),*) | |
| }; | |
| (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT | |
| [$( $var:ident: $typ:ty ),*] | |
| ) => { | |
| {$( $var:$typ ),*} | |
| }; | |
| (ITEM_PATTERN $name:ident $item:ident: UNIT [] | |
| ) => { | |
| $name::$item | |
| }; | |
| (ITEM_PATTERN $name:ident $item:ident: TUPLE | |
| [$( ref $var:ident ),*] | |
| ) => { | |
| $name::$item ($( ref $var ),*) | |
| }; | |
| (ITEM_PATTERN $name:ident $item:ident: STRUCT | |
| [$( ref $var:ident ),*] | |
| ) => { | |
| $name::$item {$( ref $var ),*} | |
| }; | |
| // This one should match all allowed sequences in "funcs" but not match | |
| // anything else. | |
| // This is to contrast FIND_* clauses which just find stuff they need and | |
| // skip everything else completely | |
| (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt from() $($tail:tt)*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*) | |
| => { quick_error!(ERROR_CHECK $imode $($tail)*); }; | |
| (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK TUPLE $($tail)*); }; | |
| (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) | |
| => { quick_error!(ERROR_CHECK STRUCT $($tail)*); }; | |
| (ERROR_CHECK $imode:tt ) => {}; | |
| // Utility functions | |
| (IDENT $ident:ident) => { $ident } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment