-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathcomponents.rs
More file actions
59 lines (55 loc) · 1.58 KB
/
components.rs
File metadata and controls
59 lines (55 loc) · 1.58 KB
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
use quote::quote;
use syn::DeriveInput;
pub(crate) fn expand_components(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let variants = match input.data {
syn::Data::Enum(syn::DataEnum { ref variants, .. }) => variants,
_ => panic!("this derive macro only works on enums"),
};
let components = impl_components(input.ident, variants);
Ok(quote! {
#components
})
}
fn impl_components(
ident: syn::Ident,
variants: &syn::punctuated::Punctuated<syn::Variant, syn::token::Comma>,
) -> proc_macro2::TokenStream {
let components = variants.iter().map(|v| {
let name = &v.ident;
if name == "NoModel" {
quote! {
Self::#name(n) => *n
}
} else {
quote! {
Self::#name(residual) => residual.components()
}
}
});
let subset = variants.iter().map(|v| {
let name = &v.ident;
if name == "NoModel" {
quote! {
Self::#name(n) => Self::#name(component_list.len())
}
} else {
quote! {
Self::#name(residual) => Self::#name(residual.subset(component_list))
}
}
});
quote! {
impl Components for #ident {
fn components(&self) -> usize {
match self {
#(#components,)*
}
}
fn subset(&self, component_list: &[usize]) -> Self {
match self {
#(#subset,)*
}
}
}
}
}