11use proc_macro2:: { Span , TokenStream } ;
22use quote:: { quote, quote_spanned} ;
33use syn:: {
4- parse_quote, punctuated:: Punctuated , spanned:: Spanned , Data , DeriveInput , Fields , GenericParam ,
5- Generics , Path , Token ,
4+ parse_quote, punctuated:: Punctuated , spanned:: Spanned , Data , DeriveInput , Fields , GenericParam , Generics , Ident , Path , Token
65} ;
76
87pub fn do_derive_schema ( input : DeriveInput ) -> syn:: Result < TokenStream > {
@@ -25,10 +24,12 @@ pub fn do_derive_schema(input: DeriveInput) -> syn::Result<TokenStream> {
2524 let ty = generator. generate_type ( & input. data , span, name. to_string ( ) ) ?;
2625
2726 let postcard_schema = & generator. postcard_schema ;
27+ let insta_test = generator. generate_snapshot_test ( name) ;
2828 let expanded = quote ! {
2929 impl #impl_generics #postcard_schema:: Schema for #name #ty_generics #where_clause {
3030 const SCHEMA : & ' static #postcard_schema:: schema:: DataModelType = #ty;
3131 }
32+ #insta_test
3233 } ;
3334
3435 Ok ( expanded)
@@ -37,13 +38,15 @@ pub fn do_derive_schema(input: DeriveInput) -> syn::Result<TokenStream> {
3738struct Generator {
3839 postcard_schema : Path ,
3940 bound : Option < Punctuated < syn:: WherePredicate , Token ! [ , ] > > ,
41+ snapshot : bool
4042}
4143
4244impl Generator {
4345 fn new ( input : & DeriveInput ) -> syn:: Result < Self > {
4446 let mut generator = Self {
4547 postcard_schema : parse_quote ! ( :: postcard_schema_ng) ,
4648 bound : None ,
49+ snapshot : false
4750 } ;
4851 for attr in & input. attrs {
4952 if attr. path ( ) . is_ident ( "postcard" ) {
@@ -67,13 +70,42 @@ impl Generator {
6770 return Ok ( ( ) ) ;
6871 }
6972
73+ // #[postcard(snapshot)]
74+ if meta. path . is_ident ( "snapshot" ) {
75+ if input. generics . params . iter ( ) . filter ( |x|!matches ! ( x, GenericParam :: Lifetime ( _) ) ) . count ( ) != 0 {
76+ return Err ( syn:: Error :: new ( input. span ( ) , "snapshot testing with generic schemas are not yet supported" ) ) ;
77+ }
78+ generator. snapshot = true ;
79+ return Ok ( ( ) )
80+ }
81+
82+
7083 Err ( meta. error ( "unsupported #[postcard] attribute" ) )
7184 } ) ?;
7285 }
7386 }
7487 Ok ( generator)
7588 }
7689
90+
91+ fn generate_snapshot_test ( & self , ident : & Ident ) -> TokenStream {
92+ if self . snapshot {
93+ let postcard_schema = & self . postcard_schema ;
94+ let test_name = Ident :: new ( format ! ( "postcard_snapshot_{}" , ident. to_string( ) ) . as_str ( ) , ident. span ( ) ) ;
95+ quote ! {
96+ #[ cfg( test) ]
97+ #[ test]
98+ #[ allow( non_snake_case) ]
99+ fn #test_name( ) {
100+ #postcard_schema:: impls:: insta:: assert_debug_snapshot!( #ident:: SCHEMA ) ;
101+ }
102+ }
103+ } else {
104+ TokenStream :: default ( )
105+ }
106+ }
107+
108+
77109 fn generate_type (
78110 & self ,
79111 data : & Data ,
0 commit comments