Add option types for top-level commands
This commit is contained in:
		
							
								
								
									
										46
									
								
								extract_macro/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								extract_macro/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
# This file is automatically @generated by Cargo.
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
version = 3
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "extract_macro"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "quote",
 | 
			
		||||
 "syn",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "proc-macro2"
 | 
			
		||||
version = "1.0.78"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "unicode-ident",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "quote"
 | 
			
		||||
version = "1.0.35"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "syn"
 | 
			
		||||
version = "2.0.49"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2",
 | 
			
		||||
 "quote",
 | 
			
		||||
 "unicode-ident",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "unicode-ident"
 | 
			
		||||
version = "1.0.12"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
 | 
			
		||||
							
								
								
									
										11
									
								
								extract_macro/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								extract_macro/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "extract_macro"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
[lib]
 | 
			
		||||
proc-macro = true
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
quote = "1.0.35"
 | 
			
		||||
syn = { version = "2.0.49", features = ["full"] }
 | 
			
		||||
							
								
								
									
										52
									
								
								extract_macro/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								extract_macro/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
use proc_macro::TokenStream;
 | 
			
		||||
use syn::{spanned::Spanned, Data, Fields};
 | 
			
		||||
 | 
			
		||||
#[proc_macro_derive(Extract)]
 | 
			
		||||
pub fn extract(input: TokenStream) -> TokenStream {
 | 
			
		||||
    let ast = syn::parse_macro_input!(input);
 | 
			
		||||
 | 
			
		||||
    impl_extract(&ast)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn impl_extract(ast: &syn::DeriveInput) -> TokenStream {
 | 
			
		||||
    let name = &ast.ident;
 | 
			
		||||
 | 
			
		||||
    match &ast.data {
 | 
			
		||||
        Data::Struct(st) => match &st.fields {
 | 
			
		||||
            Fields::Named(fields) => {
 | 
			
		||||
                let extracted = fields.named.iter().map(|field| {
 | 
			
		||||
                    let ident = &field.ident;
 | 
			
		||||
                    let ty = &field.ty;
 | 
			
		||||
 | 
			
		||||
                    quote::quote_spanned! {field.span()=>
 | 
			
		||||
                        #ident : crate::utils::extract_arg!(ctx, #ident, #ty)
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                TokenStream::from(quote::quote! {
 | 
			
		||||
                    impl Extract for #name {
 | 
			
		||||
                        fn extract(ctx: crate::ApplicationContext) -> Self {
 | 
			
		||||
                            Self {
 | 
			
		||||
                                #(#extracted,)*
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
            Fields::Unit => TokenStream::from(quote::quote! {
 | 
			
		||||
                impl Extract for #name {
 | 
			
		||||
                    fn extract(ctx: crate::ApplicationContext) -> Self {
 | 
			
		||||
                        Self {}
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }),
 | 
			
		||||
            _ => {
 | 
			
		||||
                panic!("Only named/unit structs can derive Extract");
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        _ => {
 | 
			
		||||
            panic!("Only structs can derive Extract");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user