1 #![allow(unused_macros, unused_macro_rules)] 2 3 #[path = "../debug/mod.rs"] 4 pub mod debug; 5 6 use std::str::FromStr; 7 use syn::parse::Result; 8 9 macro_rules! errorf { 10 ($($tt:tt)*) => {{ 11 use ::std::io::Write; 12 let stderr = ::std::io::stderr(); 13 write!(stderr.lock(), $($tt)*).unwrap(); 14 }}; 15 } 16 17 macro_rules! punctuated { 18 ($($e:expr,)+) => {{ 19 let mut seq = ::syn::punctuated::Punctuated::new(); 20 $( 21 seq.push($e); 22 )+ 23 seq 24 }}; 25 26 ($($e:expr),+) => { 27 punctuated!($($e,)+) 28 }; 29 } 30 31 macro_rules! snapshot { 32 ($($args:tt)*) => { 33 snapshot_impl!(() $($args)*) 34 }; 35 } 36 37 macro_rules! snapshot_impl { 38 (($expr:ident) as $t:ty, @$snapshot:literal) => { 39 let tokens = crate::macros::TryIntoTokens::try_into_tokens($expr).unwrap(); 40 let $expr: $t = syn::parse_quote!(#tokens); 41 let debug = crate::macros::debug::Lite(&$expr); 42 if !cfg!(miri) { 43 #[allow(clippy::needless_raw_string_hashes)] // https://github.com/mitsuhiko/insta/issues/389 44 { 45 insta::assert_debug_snapshot!(debug, @$snapshot); 46 } 47 } 48 }; 49 (($($expr:tt)*) as $t:ty, @$snapshot:literal) => {{ 50 let tokens = crate::macros::TryIntoTokens::try_into_tokens($($expr)*).unwrap(); 51 let syntax_tree: $t = syn::parse_quote!(#tokens); 52 let debug = crate::macros::debug::Lite(&syntax_tree); 53 if !cfg!(miri) { 54 #[allow(clippy::needless_raw_string_hashes)] 55 { 56 insta::assert_debug_snapshot!(debug, @$snapshot); 57 } 58 } 59 syntax_tree 60 }}; 61 (($($expr:tt)*) , @$snapshot:literal) => {{ 62 let syntax_tree = $($expr)*; 63 let debug = crate::macros::debug::Lite(&syntax_tree); 64 if !cfg!(miri) { 65 #[allow(clippy::needless_raw_string_hashes)] 66 { 67 insta::assert_debug_snapshot!(debug, @$snapshot); 68 } 69 } 70 syntax_tree 71 }}; 72 (($($expr:tt)*) $next:tt $($rest:tt)*) => { 73 snapshot_impl!(($($expr)* $next) $($rest)*) 74 }; 75 } 76 77 pub trait TryIntoTokens { 78 #[allow(dead_code)] try_into_tokens(self) -> Result<proc_macro2::TokenStream>79 fn try_into_tokens(self) -> Result<proc_macro2::TokenStream>; 80 } 81 82 impl<'a> TryIntoTokens for &'a str { try_into_tokens(self) -> Result<proc_macro2::TokenStream>83 fn try_into_tokens(self) -> Result<proc_macro2::TokenStream> { 84 let tokens = proc_macro2::TokenStream::from_str(self)?; 85 Ok(tokens) 86 } 87 } 88 89 impl TryIntoTokens for proc_macro2::TokenStream { try_into_tokens(self) -> Result<proc_macro2::TokenStream>90 fn try_into_tokens(self) -> Result<proc_macro2::TokenStream> { 91 Ok(self) 92 } 93 } 94