From 3934f0e59c7d05b8e59d4dfbe5611aa39a9bc10e Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Sun, 13 Nov 2022 22:12:13 +0800 Subject: [PATCH] Optimize `cmd-impl` --- Cargo.lock | 1 - bin/subalfred/src/command/impl/Cargo.toml | 1 - .../src/command/impl/debug/Cargo.lock | 53 +++++++++++++++++++ bin/subalfred/src/command/impl/src/lib.rs | 38 ++++++------- 4 files changed, 70 insertions(+), 23 deletions(-) create mode 100644 bin/subalfred/src/command/impl/debug/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index c31f1623..84c880a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -289,7 +289,6 @@ dependencies = [ name = "cmd-impl" version = "0.9.0-rc16" dependencies = [ - "proc-macro2", "quote", "syn", ] diff --git a/bin/subalfred/src/command/impl/Cargo.toml b/bin/subalfred/src/command/impl/Cargo.toml index aedd6ff4..08d6ac07 100644 --- a/bin/subalfred/src/command/impl/Cargo.toml +++ b/bin/subalfred/src/command/impl/Cargo.toml @@ -13,7 +13,6 @@ version = "0.9.0-rc16" proc-macro = true [dependencies] -proc-macro2 = { version = "1.0" } quote = { version = "1.0" } syn = { version = "1.0", features = ["full"] } diff --git a/bin/subalfred/src/command/impl/debug/Cargo.lock b/bin/subalfred/src/command/impl/debug/Cargo.lock new file mode 100644 index 00000000..299c5aec --- /dev/null +++ b/bin/subalfred/src/command/impl/debug/Cargo.lock @@ -0,0 +1,53 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cmd-impl" +version = "0.9.0-rc16" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "cmd-impl-debug" +version = "0.0.0" +dependencies = [ + "cmd-impl", +] + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" diff --git a/bin/subalfred/src/command/impl/src/lib.rs b/bin/subalfred/src/command/impl/src/lib.rs index 7d063834..9cb924c6 100644 --- a/bin/subalfred/src/command/impl/src/lib.rs +++ b/bin/subalfred/src/command/impl/src/lib.rs @@ -1,31 +1,25 @@ // proc-macro use proc_macro::TokenStream; // crates.io -use proc_macro2::TokenStream as TokenStream2; use syn::*; /// Quickly define and implement a command containing serval subcommands. #[proc_macro_attribute] pub fn cmd(_: TokenStream, input: TokenStream) -> TokenStream { - let item_enum = syn::parse_macro_input!(input as ItemEnum); + let cmd_enum = syn::parse_macro_input!(input as ItemEnum); // #[cfg(feature = "debug")] - // dbg!(&item_enum); + // dbg!(&cmd_enum); - let ItemEnum { attrs, vis, ident, variants, .. } = item_enum; - let variant_runs = variants - .iter() - .map(|v| v.ident.to_string().parse::().unwrap()) - .map(|n| { - quote::quote! { - Self::#n(cmd) => { cmd.run() } - } - }) - .collect::>(); - let variants = variants + let ItemEnum { + attrs: cmd_attrs, vis: cmd_vis, ident: cmd_name, variants: cmd_variants, .. + } = cmd_enum; + let cmd_variants_names = + cmd_variants.iter().map(|variant| variant.ident.clone()).collect::>(); + let cmd_variants = cmd_variants .into_iter() .map(|Variant { attrs, ident, .. }| { - let cmd = format!("{}Cmd", ident).parse::().unwrap(); + let cmd = quote::format_ident!("{ident}Cmd"); quote::quote! { #(#attrs)* @@ -36,14 +30,16 @@ pub fn cmd(_: TokenStream, input: TokenStream) -> TokenStream { quote::quote! { #[derive(Debug, clap::Subcommand)] - #(#attrs)* - #vis enum #ident { - #(#variants,)* + #(#cmd_attrs)* + #cmd_vis enum #cmd_name { + #(#cmd_variants,)* } - impl #ident { - #vis fn run(&self) -> crate::prelude::Result<()> { + impl #cmd_name { + #cmd_vis fn run(&self) -> crate::prelude::Result<()> { match self { - #(#variant_runs,)* + #( + Self::#cmd_variants_names(cmd) => cmd.run(), + )* } } }