David Tolnay | 7d8b331 | 2019-03-10 01:26:11 -0800 | [diff] [blame] | 1 | extern crate proc_macro2; |
| 2 | |
| 3 | use syn; |
| 4 | use syn::parse::{Parse, Result}; |
| 5 | |
David Tolnay | dd12556 | 2017-12-31 02:16:22 -0500 | [diff] [blame] | 6 | #[macro_export] |
| 7 | macro_rules! errorf { |
| 8 | ($($tt:tt)*) => {{ |
| 9 | use ::std::io::Write; |
| 10 | let stderr = ::std::io::stderr(); |
| 11 | write!(stderr.lock(), $($tt)*).unwrap(); |
| 12 | }}; |
| 13 | } |
| 14 | |
| 15 | #[macro_export] |
David Tolnay | f2cfd72 | 2017-12-31 18:02:51 -0500 | [diff] [blame] | 16 | macro_rules! punctuated { |
David Tolnay | a0834b4 | 2018-01-01 21:30:02 -0800 | [diff] [blame] | 17 | ($($e:expr,)+) => {{ |
David Tolnay | f2cfd72 | 2017-12-31 18:02:51 -0500 | [diff] [blame] | 18 | let mut seq = ::syn::punctuated::Punctuated::new(); |
David Tolnay | dd12556 | 2017-12-31 02:16:22 -0500 | [diff] [blame] | 19 | $( |
David Tolnay | a0834b4 | 2018-01-01 21:30:02 -0800 | [diff] [blame] | 20 | seq.push($e); |
| 21 | )+ |
David Tolnay | f2cfd72 | 2017-12-31 18:02:51 -0500 | [diff] [blame] | 22 | seq |
David Tolnay | dd12556 | 2017-12-31 02:16:22 -0500 | [diff] [blame] | 23 | }}; |
| 24 | |
| 25 | ($($e:expr),+) => { |
David Tolnay | f2cfd72 | 2017-12-31 18:02:51 -0500 | [diff] [blame] | 26 | punctuated!($($e,)+) |
David Tolnay | dd12556 | 2017-12-31 02:16:22 -0500 | [diff] [blame] | 27 | }; |
| 28 | } |
David Tolnay | 7d8b331 | 2019-03-10 01:26:11 -0800 | [diff] [blame] | 29 | |
| 30 | #[macro_export] |
| 31 | macro_rules! snapshot { |
| 32 | ($($args:tt)*) => { |
| 33 | snapshot_impl!(() $($args)*) |
| 34 | }; |
| 35 | } |
| 36 | |
| 37 | #[macro_export] |
| 38 | macro_rules! snapshot_impl { |
| 39 | (($($expr:tt)*) as $t:ty) => {{ |
| 40 | let syntax_tree = ::macros::Tokens::parse::<$t>($($expr)*).unwrap(); |
| 41 | insta::assert_debug_snapshot_matches!(syntax_tree); |
| 42 | syntax_tree |
| 43 | }}; |
| 44 | (($($expr:tt)*)) => {{ |
| 45 | let syntax_tree = $($expr)*; |
| 46 | insta::assert_debug_snapshot_matches!(syntax_tree); |
| 47 | syntax_tree |
| 48 | }}; |
| 49 | (($($expr:tt)*) $next:tt $($rest:tt)*) => { |
| 50 | snapshot_impl!(($($expr)* $next) $($rest)*) |
| 51 | }; |
| 52 | } |
| 53 | |
| 54 | pub trait Tokens { |
| 55 | fn parse<T: Parse>(self) -> Result<T>; |
| 56 | } |
| 57 | |
| 58 | impl<'a> Tokens for &'a str { |
| 59 | fn parse<T: Parse>(self) -> Result<T> { |
| 60 | syn::parse_str(self) |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | impl Tokens for proc_macro2::TokenStream { |
| 65 | fn parse<T: Parse>(self) -> Result<T> { |
| 66 | syn::parse2(self) |
| 67 | } |
| 68 | } |