lib::quick_error!
[−]
[src]
macro_rules! quick_error { ( $(#[$meta:meta])* pub enum $name:ident { $($chunks:tt)* } ) => { quick_error!(SORT [pub enum $name $(#[$meta])* ] enum [] items [] buf [] queue [ $($chunks)* ]); }; ( $(#[$meta:meta])* enum $name:ident { $($chunks:tt)* } ) => { quick_error!(SORT [enum $name $(#[$meta])* ] enum [] items [] buf [] queue [ $($chunks)* ]); }; /* macro_rules! sort { ({ $( $(#[$meta:meta])* => $item:ident )* } { $(#[$bufmeta:meta])* } { #[$nextmeta:meta] $($tail:tt)* }) => { sort!({ $( $(#[$meta])* => $item )* } { $(#[$bufmeta])* #[$nextmeta] } { $($tail)* }); }; ({ $( $(#[$meta:meta])* => $item:ident )* } { $(#[$bufmeta:meta])* } { $name:ident $($tail:tt)* }) => { sort!({ $( $(#[$meta])* => $item )* $(#[$bufmeta])* => $name } {} { $($tail)* }); }; ({ $( $(#[$meta:meta])* => $item:ident )* } {} {}) => { #[derive(Debug)] pub enum Test { $( $(#[$meta])* $item, )* } }; } */ // Queue is empty, can do the work (SORT [enum $name:ident $(#[$meta:meta])* ] enum [ $( $(#[$emeta:meta])* => $eitem:ident $( ( $($etyp:ty),* ) )* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ ] queue [ ] ) => { $(#[$meta])* enum $name { $( $(#[$emeta])* $eitem $(( $($etyp),* ))*, )* } quick_error!(IMPLEMENTATIONS $name { $( $iitem $(( $($ivar: $ityp),* ))* { $($ifuncs)* } )* }); $( quick_error!(ERROR_CHECK $($ifuncs)*); )* }; (SORT [pub enum $name:ident $(#[$meta:meta])* ] enum [ $( $(#[$emeta:meta])* => $eitem:ident $( ( $($etyp:ty),* ) )* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ ] queue [ ] ) => { $(#[$meta])* pub enum $name { $( $(#[$emeta])* $eitem $(( $($etyp),* ))*, )* } quick_error!(IMPLEMENTATIONS $name { $( $iitem $(( $($ivar: $ityp),* ))* { $($ifuncs)* } )* }); $( quick_error!(ERROR_CHECK $($ifuncs)*); )* }; // Add meta to buffer (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* ] queue [ #[$qmeta:meta] $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* ] buf [ $( #[$bmeta] )* #[$qmeta] ] queue [ $($tail)* ]); }; // Add ident to buffer (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* ] queue [ $qitem:ident $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [ $( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* ] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* ] buf [ $(#[$bmeta])* => $qitem ] queue [ $($tail)* ]); }; // Flush buffer on meta after ident (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* => $bitem:ident $(( $($bvar:ident : $btyp:ty),* ))* ] queue [ #[$qmeta:meta] $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* $(#[$bmeta])* => $bitem $(( $($btyp),* ))*] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* $bitem $(( $($bvar:$btyp),* ))* {} ] buf [ #[$qmeta] ] queue [ $($tail)* ]); }; // Add parenthesis (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* => $bitem:ident ] queue [ ( $( $qvar:ident : $qtyp:ty ),* ) $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* ] buf [ $( #[$bmeta] )* => $bitem ( $( $qvar:$qtyp ),* ) ] queue [ $($tail)* ]); }; // Add braces and flush always on braces (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* => $bitem:ident $(( $($bvar:ident : $btyp:ty),* ))* ] queue [ { $($qfuncs:tt)* } $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* $(#[$bmeta])* => $bitem $(( $($btyp),* ))* ] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* $bitem $(( $($bvar:$btyp),* ))* { $($qfuncs)* } ] buf [ ] queue [ $($tail)* ]); }; // Flush buffer on double ident (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* => $bitem:ident $(( $($bvar:ident : $btyp:ty),* ))* ] queue [ $qitem:ident $($tail:tt)* ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* $(#[$bmeta])* => $bitem $(( $($btyp),* ))*] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* $bitem $(( $($bvar:$btyp),* ))* {} ] buf [ => $qitem ] queue [ $($tail)* ]); }; // Flush buffer on end (SORT [$($def:tt)*] enum [ $( $(#[$emeta:meta])* => $eitem:ident $(( $($etyp:ty),* ))* )* ] items [ $( $iitem:ident $(( $($ivar:ident : $ityp:ty),* ))* { $($ifuncs:tt)* } )* ] buf [ $( #[$bmeta:meta] )* => $bitem:ident $(( $($bvar:ident : $btyp:ty),* ))* ] queue [ ] ) => { quick_error!(SORT [$($def)* ] enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )* $(#[$bmeta])* => $bitem $(( $($btyp),* ))* ] items [ $( $iitem $(( $($ivar:$ityp),* ))* { $($ifuncs)* } )* $bitem $(( $($bvar:$btyp),* ))* {} ] buf [ ] queue [ ]); }; (IMPLEMENTATIONS $name:ident { $( $item:ident $( ( $($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 { $( &$name::$item $( ( $(ref $var),* ) )* => { quick_error!(FIND_DISPLAY_IMPL $item self fmt [ $( ( $($var)* ) )* ] { $($funcs)* }) } )* } } } #[allow(unused)] impl ::std::error::Error for $name { fn description(&self) -> &str { match self { $( &$name::$item $( ( $(ref $var),* ) )* => { quick_error!(FIND_DESCRIPTION_IMPL $item self fmt [ $( ( $($var)* ) )* ] { $($funcs)* }) } )* } } fn cause(&self) -> Option<&::std::error::Error> { match self { $( &$name::$item $( ( $(ref $var),* ) )* => { quick_error!(FIND_CAUSE_IMPL $item [ $( ( $($var)* ) )* ] { $($funcs)* }) } )* } } } $( quick_error!(FIND_FROM_IMPL $name $item [ $( ( $($var:$typ)* ) )* ] { $($funcs)* }); )* }; (FIND_DISPLAY_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { display($($exprs:expr),*) $($tail:tt)* } ) => { write!($fmt, $($exprs),*) }; (FIND_DISPLAY_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { $t:tt $($tail:tt)* } ) => { quick_error!(FIND_DISPLAY_IMPL $item $me $fmt [ $( ( $($var)* ) )* ] { $($tail)* }) }; (FIND_DISPLAY_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { } ) => { write!($fmt, "{}", ::std::error::Error::description($me)) }; (FIND_DESCRIPTION_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { description($expr:expr) $($tail:tt)* } ) => { $expr }; (FIND_DESCRIPTION_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { $t:tt $($tail:tt)* } ) => { quick_error!(FIND_DESCRIPTION_IMPL $item $me $fmt [ $( ( $($var)* ) )* ] { $($tail)* }) }; (FIND_DESCRIPTION_IMPL $item:ident $me:ident $fmt:ident [ $( ( $($var:ident)* ) )* ] { } ) => { stringify!($item) }; (FIND_CAUSE_IMPL $item:ident [ $( ( $($var:ident)* ) )* ] { cause($expr:expr) $($tail:tt)* } ) => { Some($expr) }; (FIND_CAUSE_IMPL $item:ident [ $( ( $($var:ident)* ) )* ] { $t:tt $($tail:tt)* } ) => { quick_error!(FIND_CAUSE_IMPL $item [ $( ( $($var)* ) )* ] { $($tail)* }) }; (FIND_CAUSE_IMPL $item:ident [ $( ( $($var:ident)* ) )* ] { } ) => { None }; (FIND_FROM_IMPL $name:ident $item:ident [ $( ( $($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 [ $( ( $($var:$typ)* ) )* ] { $($tail)* }); }; (FIND_FROM_IMPL $name:ident $item:ident [ ] { 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 [ ] { $($tail)* }); }; (FIND_FROM_IMPL $name:ident $item:ident [ $( ( $($var:ident : $typ:ty)* ) )* ] { from($fvar:ident : $ftyp:ty) -> ($($expr:expr),*) $($tail:tt)* } ) => { impl From<$ftyp> for $name { fn from($fvar: $ftyp) -> $name { $name::$item($($expr),*) } } quick_error!(FIND_FROM_IMPL $name $item [ $( ( $($var:$typ)* ) )* ] { $($tail)* }); }; (FIND_FROM_IMPL $name:ident $item:ident [ $( ( $($var:ident : $typ:ty)* ) )* ] { $t:tt $($tail:tt)* } ) => { quick_error!(FIND_FROM_IMPL $name $item[ $( ( $($var:$typ)* ) )* ] { $($tail)* }); }; (FIND_FROM_IMPL $name:ident $item:ident [ $( ( $($var:ident : $typ:ty)* ) )* ] { } ) => { }; // 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 display($($exprs:expr),*) $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK description($expr:expr) $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK cause($expr:expr) $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK from() $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK from($ftyp:ty) $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK from($fvar:ident : $ftyp:ty) -> ($($e:expr),*) $($tail:tt)*) => { quick_error!(ERROR_CHECK $($tail)*); }; (ERROR_CHECK) => {}; }
Main macro that does all the work