summaryrefslogtreecommitdiffstats
path: root/starship_module_config_derive
diff options
context:
space:
mode:
authorZhenhui Xie <xiezh0831@126.com>2019-09-30 20:10:35 +0800
committerMatan Kushner <hello@matchai.me>2019-09-30 21:10:35 +0900
commitdd0b1a1aa2c36bf2df4db9c11a6517a018ffa100 (patch)
treee2bb1b1bc6b60cb23848af9c625d21575250ecf0 /starship_module_config_derive
parent9e9eb6a8ef87f7b93dc07e0cf068ccb1a6ce588c (diff)
refactor: Refactoring config (#383)
This PR refactors config and puts configuration files for all modules in `configs/`.
Diffstat (limited to 'starship_module_config_derive')
-rw-r--r--starship_module_config_derive/Cargo.toml28
-rw-r--r--starship_module_config_derive/src/lib.rs76
2 files changed, 104 insertions, 0 deletions
diff --git a/starship_module_config_derive/Cargo.toml b/starship_module_config_derive/Cargo.toml
new file mode 100644
index 000000000..95df616ca
--- /dev/null
+++ b/starship_module_config_derive/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "starship_module_config_derive"
+version = "0.20.0"
+edition = "2018"
+authors = ["Matan Kushner <hello@matchai.me>"]
+homepage = "https://starship.rs"
+documentation = "https://starship.rs/guide/"
+repository = "https://github.com/starship/starship"
+readme = "README.md"
+license = "ISC"
+keywords = ["prompt", "shell", "bash", "fish", "zsh"]
+categories = ["command-line-utilities"]
+description = """
+The cross-shell prompt for astronauts. ☄🌌️
+"""
+exclude = ["docs/**/*"]
+
+[lib]
+name = "starship_module_config_derive"
+proc-macro = true
+
+[dependencies]
+proc-macro2 = "~1"
+quote = "~1"
+syn = "~1"
+
+[dev-dependencies]
+starship = { version = "0.20.0", path = "../starship" }
diff --git a/starship_module_config_derive/src/lib.rs b/starship_module_config_derive/src/lib.rs
new file mode 100644
index 000000000..eeddf5a8b
--- /dev/null
+++ b/starship_module_config_derive/src/lib.rs
@@ -0,0 +1,76 @@
+extern crate proc_macro;
+extern crate proc_macro2;
+
+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: <#ty>::from_config(config.get(stringify!(#ident))?)?,
+ };
+
+ 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 {
+ #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
+ }
+ })
+}