1 use proc_macro::TokenStream;
2 use quote::{quote, quote_spanned};
3 use syn::{parse, parse_macro_input, Ident, Token, Visibility};
4
5 use build_info_common::BuildInfo;
6
7 mod init_value;
8 use init_value::init_value;
9
10 struct FunctionSyntax {
11 definition_crate: Ident,
12 visibility: Option<Visibility>,
13 id: Ident,
14 }
15
16 impl parse::Parse for FunctionSyntax {
parse(input: parse::ParseStream) -> parse::Result<Self>17 fn parse(input: parse::ParseStream) -> parse::Result<Self> {
18 let definition_crate = input.parse::<Ident>()?;
19 let visibility: Option<Visibility> = input.parse().ok();
20 input.parse::<Token![fn]>()?;
21 let id = input.parse::<Ident>()?;
22 Ok(FunctionSyntax {
23 definition_crate,
24 visibility,
25 id,
26 })
27 }
28 }
29
build_info(input: TokenStream, build_info: BuildInfo) -> TokenStream30 pub fn build_info(input: TokenStream, build_info: BuildInfo) -> TokenStream {
31 let FunctionSyntax {
32 definition_crate,
33 visibility,
34 id,
35 } = parse_macro_input!(input as FunctionSyntax);
36 let visibility = visibility.map_or(quote!(), |vis| quote!(#vis));
37
38 let mut tokens = proc_macro2::TokenStream::new();
39 init_value(&build_info, &mut tokens, &definition_crate);
40
41 #[allow(clippy::let_and_return)]
42 let output = quote_spanned! {
43 proc_macro::Span::mixed_site().into() =>
44 #visibility fn #id() -> &'static #definition_crate::BuildInfo {
45 #definition_crate::lazy_static! {
46 static ref VERSION: #definition_crate::BuildInfo = #tokens;
47 }
48 &VERSION
49 }
50 };
51
52 // println!("{}", output.to_string());
53 output.into()
54 }
55