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
use crate::ir::{Attributes, Attribute, Identifier};
use proc_macro2::TokenStream;
use quote::TokenStreamExt;
use quote::quote;
use std::convert::TryFrom;
pub fn ligen_project(attributes: TokenStream) -> TokenStream {
let attributes = Attributes::try_from(attributes).expect("Failed to parse Attributes.");
let mut output = TokenStream::new();
attributes.attributes
.into_iter()
.for_each(|attribute| output.append_all(to_project_tokens(&attribute)));
output
}
fn to_project_tokens(attribute: &Attribute) -> TokenStream {
match attribute {
Attribute::Literal(lit) => {
let ident = Identifier::new(format!("ligen_{}", &lit.to_string()).as_str());
quote! {#ident!();}
}
Attribute::Named(_, _) => panic!("Named variant should only be used inside groups"),
Attribute::Group(ident, group) => {
let mut gp = TokenStream::new();
group
.attributes
.clone()
.into_iter()
.enumerate()
.for_each(|x| {
if let (index, Attribute::Literal(lit)) = x {
let name = Identifier::new(&lit.to_string());
gp.append_all(quote! {#name});
if index + 1 < group.attributes.len() {
gp.append_all(quote! {, })
}
} else {
panic!("Group contains Named variant")
}
});
let ident = Identifier::new(format!("ligen_{}", &ident.name).as_str());
quote! {#ident!(#gp);}
}
}
}