singletonum_derive/
lib.rs1#[macro_use]
2extern crate quote;
3extern crate syn;
4extern crate proc_macro;
5#[macro_use]
6extern crate failure;
7extern crate heck;
8
9use failure::Error;
10use syn::Ident;
11use proc_macro::TokenStream;
12use quote::quote;
13use heck::ShoutySnakeCase;
14
15#[proc_macro_derive(Singleton)]
16pub fn singleton_derive(input: TokenStream) -> TokenStream {
17 let s = input.to_string();
19
20 let ast = syn::parse_derive_input(&s).unwrap();
22
23 let gen = impl_singleton(&ast);
25
26 gen.parse().unwrap()
28}
29
30fn impl_singleton(ast: &syn::DeriveInput) -> quote::Tokens {
31 let name = &ast.ident;
32 let static_var_name = format!("{}_SINGLETON", name.as_ref().to_shouty_snake_case());
33 let static_var_ident = Ident::from(static_var_name);
34 quote! {
35 static #static_var_ident: singletonum::OnceCell<#name> = singletonum::OnceCell::INIT;
36
37 impl singletonum::Singleton for #name {
38 fn get_instance(init: &Self::Init) -> &'static Self {
39 #static_var_ident.get_or_init(|| Self::init(init))
40 }
41 }
42 }
43}