#![feature(proc_macro_diagnostic)]
#![warn(clippy::all)]
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{parse_macro_input, Expr, Ident, Lit, Result, Token};
struct GeneratedModInput {
path_after_out: Expr,
mod_name: Ident,
}
impl Parse for GeneratedModInput {
fn parse(input: ParseStream) -> Result<Self> {
Ok(GeneratedModInput {
path_after_out: input.parse()?,
mod_name: input.parse()?,
})
}
}
#[proc_macro]
pub fn generated_mod(tokens: TokenStream) -> TokenStream {
let params = parse_macro_input!(tokens as GeneratedModInput);
let mod_name = params.mod_name;
let mut path_after_out: String = "".to_string();
match ¶ms.path_after_out {
Expr::Lit(pao) => match &pao.lit {
Lit::Str(pao) => path_after_out = pao.value(),
_ => {
let _ = params
.path_after_out
.span()
.unstable()
.error("Paths are strings, and strings only.");
}
},
_ => {
let _ = params
.path_after_out
.span()
.unstable()
.error("Paths are string literals, and string literals only.");
}
}
let final_path = format!(
"\"{}/{}\"",
&std::env::var("OUT_DIR").unwrap(),
path_after_out
);
{
quote! {
#[path = #final_path]
pub mod #mod_name;
}
}
.into()
}