Skip to main content

rpk_macros/
lib.rs

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}