1extern crate proc_macro;
2
3use rpk_config::compiler::compile;
4
5mod build;
6
7#[proc_macro]
8pub fn configure_keyboard(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
9 build::configure_keyboard(proc_macro2::TokenStream::from(input)).into()
10}
11
12#[proc_macro]
13pub fn layout_config(conf: proc_macro::TokenStream) -> proc_macro::TokenStream {
14 fn error(message: &str) -> proc_macro::TokenStream {
15 format!(
16 r####"{{compile_error!(r###"{}"###); const M: [u16; 0] = [];&M}}"####,
17 message
18 )
19 .parse()
20 .unwrap()
21 }
22
23 if let Some(proc_macro::TokenTree::Literal(item)) = conf.into_iter().next() {
24 let conf = item.to_string();
25 let mut conf = conf.as_str();
26 if conf.starts_with('r') {
27 if let Some(i) = conf.find('"') {
28 conf = &conf[i..conf.len() - i + 1];
29 }
30 }
31
32 if conf.starts_with('"') {
33 conf = &conf[1..conf.len() - 1];
34 }
35 match compile(conf) {
36 Ok(source) => {
37 let bin = source.serialize();
38 format!("{{ const M: [u16; {}] = {:?}; &M }}", bin.len(), bin)
39 .parse()
40 .unwrap()
41 }
42 Err(err) => error(err.to_string().as_str()),
43 }
44 } else {
45 error("Expected a string argument")
46 }
47}