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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::{fs::File, io::Read, path::Path};
use grass_ir::GrassIR;
use ir_expand::ExpansionContext;
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::{parse_macro_input, LitStr};
mod ir_expand;
fn grass_impl(ir: &str, span: Span) -> TokenStream {
let ir: GrassIR = match serde_json::from_str(ir) {
Err(e) => {
return syn::Error::new(span, format!("Unable to parse Grass IR {}", e.to_string()))
.to_compile_error()
.into()
}
Ok(ir) => ir,
};
let mut ctx = ExpansionContext::new(span);
let result = match ir_expand::expand_grass_ir(&ir, &mut ctx) {
Ok(_code) => {
let code = ctx.to_token_stream();
quote! {
#code;
}
}
Err(err) => err.into_compile_error(),
};
result.into()
}
#[proc_macro]
pub fn import_grass_ir_from_file(input: TokenStream) -> TokenStream {
let ir_lit = parse_macro_input!(input as LitStr);
let ir_lit_val = ir_lit.value();
let ir_path_rel: &Path = ir_lit_val.as_ref();
let manifest_path_str = env!("CARGO_MANIFEST_DIR");
let manifest_path: &Path = manifest_path_str.as_ref();
let ir_path = if ir_path_rel.is_relative() {
let mut pb = manifest_path.to_path_buf();
pb.push(ir_path_rel);
pb
} else {
ir_path_rel.to_path_buf()
};
let ir_str = match File::open(&ir_path) {
Err(e) => {
return syn::Error::new(
ir_lit.span(),
format!(
"Unable to open file \"{}\": {}",
ir_path.to_string_lossy(),
e
),
)
.to_compile_error()
.into()
}
Ok(mut fp) => {
let mut buf = String::new();
if let Err(e) = fp.read_to_string(&mut buf) {
return syn::Error::new(
ir_lit.span(),
format!(
"Unable to read file \"{}\": {}",
ir_path.to_string_lossy(),
e
),
)
.to_compile_error()
.into();
}
buf
}
};
grass_impl(ir_str.as_str(), ir_lit.span())
}
#[proc_macro]
pub fn import_grass_ir(input: TokenStream) -> TokenStream {
let ir_lit = parse_macro_input!(input as LitStr);
grass_impl(ir_lit.value().as_str(), ir_lit.span())
}