Skip to main content

pkg_macros/
lib.rs

1extern crate proc_macro;
2
3mod parse;
4
5use std::env;
6
7use proc_macro2::Span;
8use proc_macro_hack::proc_macro_hack;
9use quote::quote;
10use syn::{parse_macro_input, Error};
11
12use crate::parse::AuthorsInput;
13
14#[proc_macro_hack]
15pub fn authors(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
16    let input = parse_macro_input!(input as AuthorsInput);
17
18    let authors: Vec<String> = match env::var_os("CARGO_PKG_AUTHORS").map_or_else(
19        || Err(format!("authors environment variable not found")),
20        |s| {
21            s.to_str()
22                .map(|s| s.trim().split(';').map(ToString::to_string).collect())
23                .ok_or_else(|| {
24                    format!(
25                        "authors environment variable is not valid unicode: {}",
26                        s.to_string_lossy()
27                    )
28                })
29        },
30    ) {
31        Ok(authors) => authors,
32        Err(err) => return Error::new(Span::call_site(), err).to_compile_error().into(),
33    };
34
35    let output = match input.join {
36        Some(join) => {
37            let s: String = authors.join(&join.value());
38            quote!(#s)
39        }
40        None => quote!(&[#(#authors),*]),
41    };
42
43    output.into()
44}