1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
extern crate proc_macro;

use quote::quote;
use synstructure::BindStyle;

fn sparsable_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.bind_with(|_bi| BindStyle::RefMut).each(|bi| {
        quote! {
            #bi.sparse_init(state, metadata, ndepth)?;
        }
    });
    let crate_name = proc_macro_crate::crate_name("sppparse")
        .map(|v| syn::Ident::new(v.as_str(), proc_macro2::Span::call_site()));
    s.add_bounds(synstructure::AddBounds::Both);
    match crate_name {
		Ok(name) => {
			s.gen_impl(quote! {
				extern crate #name as sppparse;
				gen impl sppparse::SparsableTrait for @Self {
					fn sparse_init(&mut self, state: &mut sppparse::SparseState, metadata: &sppparse::SparseMetadata, depth: u32) -> Result<(), sppparse::SparseError>
					{
						let ndepth = depth+1;
						match *self { #body };
						Ok(())
					}
				}
			})
		}
		_ => {
			s.gen_impl(quote! {
				extern crate sppparse;
				gen impl sppparse::SparsableTrait for @Self {
					fn sparse_init(&mut self, state: &mut sppparse::SparseState, metadata: &sppparse::SparseMetadata, depth: u32) -> Result<(), sppparse::SparseError>
					{
						let ndepth = depth+1;
						match *self { #body };
						Ok(())
					}
				}
			})
		}
	}
}

fn sparsable_derive_inner(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.bind_with(|_bi| BindStyle::RefMut).each(|bi| {
        quote! {
            #bi.sparse_init(state, metadata, ndepth)?;
        }
    });

    s.add_bounds(synstructure::AddBounds::Fields);
    s.gen_impl(quote! {
        use crate::*;
        gen impl SparsableTrait for @Self {
            fn sparse_init(&mut self, state: &mut SparseState, metadata: &SparseMetadata, depth: u32) -> Result<(), SparseError>
            {
				let ndepth = depth+1;

                match *self { #body };
                Ok(())
            }
        }
    })
}

synstructure::decl_derive!([Sparsable] => sparsable_derive);
synstructure::decl_derive!([SparsableInner] => sparsable_derive_inner);