1
0
mirror of https://github.com/Llewellynvdm/starship.git synced 2024-06-03 17:10:50 +00:00
starship/starship_module_config_derive/src/lib.rs
Tilmann Meyer 2233683410
feat: add error messaging (#1576)
This creates a custom logger for the log crate which logs everything to a file (/tmp/starship/session_$STARSHIP_SESSION_KEY.log) and it logs everything above Warn to stderr, but only if the log file does not contain the line that should be logged resulting in an error or warning to be only logged at the first starship invocation after opening the shell.
2020-09-28 16:38:50 -04:00

77 lines
2.7 KiB
Rust

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(ModuleConfig)]
pub fn derive_module_config(input: TokenStream) -> TokenStream {
let dinput = parse_macro_input!(input as DeriveInput);
impl_module_config(dinput)
}
fn impl_module_config(dinput: DeriveInput) -> proc_macro::TokenStream {
let struct_ident = &dinput.ident;
let (_impl_generics, ty_generics, where_clause) = dinput.generics.split_for_impl();
let mut from_config = quote! {};
let mut load_config = quote! {};
if let syn::Data::Struct(data) = dinput.data {
if let syn::Fields::Named(fields_named) = data.fields {
let mut load_tokens = quote! {};
let mut from_tokens = quote! {};
for field in fields_named.named.iter() {
let ident = field.ident.as_ref().unwrap();
let ty = &field.ty;
let new_load_tokens = quote! {
if let Some(config_str) = config.get(stringify!(#ident)) {
new_module_config.#ident = new_module_config.#ident.load_config(config_str);
}
};
let new_from_tokens = quote! {
#ident: config.get(stringify!(#ident)).and_then(<#ty>::from_config)?,
};
load_tokens = quote! {
#load_tokens
#new_load_tokens
};
from_tokens = quote! {
#from_tokens
#new_from_tokens
}
}
load_config = quote! {
fn load_config(&self, config: &'a toml::Value) -> Self {
let mut new_module_config = self.clone();
if let toml::Value::Table(config) = config {
if config.get("prefix").is_some() || config.get("suffix").is_some() {
log::warn!("You're using the outdated config format! Migrate your config here: https://starship.rs/migrating-to-0.45.0/")
}
#load_tokens
}
new_module_config
}
};
from_config = quote! {
fn from_config(config: &'a toml::Value) -> Option<Self> {
let config = config.as_table()?;
Some(#struct_ident {
#from_tokens
})
}
};
}
}
TokenStream::from(quote! {
impl<'a> ModuleConfig<'a> for #struct_ident #ty_generics #where_clause {
#from_config
#load_config
}
})
}