fn handle_argument(arg: &FnArg) -> (TokenStream, Expr) {
    match arg {
        FnArg::Receiver(_) => panic!("Command callbacks cannot be member functions."),
        FnArg::Typed(pattern_type) => {
            match &*pattern_type.pat {
                Pat::Ident(ident) => {
                    let ty = &pattern_type.ty;
                    let name = &ident.ident;

                    match &**ty {
                        Type::Reference(r) => match r.elem.as_ref() {
                            Type::Slice(s) => handle_slice_argument(name, s),
                            _ => panic!("Command callbacks only accept references of slices."),
                        },
                        Type::Path(p) => {
                            if let Some(last) = p.path.segments.last() {
                                // This is gross, but since we're dealing with an
                                // AST there isn't another way to differentiate
                                // between Option and other types...
                                if last.ident.to_string() == "Option" {
                                    match &last.arguments {
                                        PathArguments::AngleBracketed(inner_ty) => {
                                            if inner_ty.args.len() != 1 {
                                                panic!("Found unrecognized Option type with multiple generic type arguments");
                                            }
                                            match inner_ty.args.last().unwrap() {
                                            GenericArgument::Type(inner_ty) => return handle_optional_argument(name, &inner_ty),
                                            _ => panic!("Found unrecognized Option generic type parameter"),
                                        }
                                        }
                                        _ => panic!("Found unrecognized, non-generic Option type"),
                                    }
                                }
                            }

                            handle_required_argument(name, &ty)
                        }
                        _ => panic!("Invalid command callback parameter type"),
                    }
                }
                _ => panic!("Command callback function takes an unhandled argument type."),
            }
        }
    }
}
// Handles a single callback function argument by generating the code for two
// pieces (returned separately in a tuple):
//
// - The code which extracts the argument from the monolithic `Values` struct.
// - The `Expr` which we'll pass in to the real command callback with the value.
Handles a single callback function argument by generating the code for two
pieces (returned separately in a tuple).

The code which extracts the argument from the monolithic `Values` struct.
The `Expr` which we'll pass in to the real command callback with the value.
Handles a single callback function argument by generating the code for two pieces ( returned separately in a tuple ) . The code which extracts the argument from the monolithic ` Values ` struct . The ` Expr ` which we ' ll pass in to the real command callback with the value .
fn handle_argument(arg: &FnArg) -> (TokenStream, Expr) {
    match arg {
        FnArg::Receiver(_) => panic!("Command callbacks cannot be member functions."),
        FnArg::Typed(pattern_type) => {
            match &*pattern_type.pat {
                Pat::Ident(ident) => {
                    let ty = &pattern_type.ty;
                    let name = &ident.ident;
                    match &**ty {
                        Type::Reference(r) => match r.elem.as_ref() {
                            Type::Slice(s) => handle_slice_argument(name, s),
                            _ => panic!("Command callbacks only accept references of slices."),
                        },
                        Type::Path(p) => {
                            if let Some(last) = p.path.segments.last() {
                                // This is gross, but since we're dealing with an
                                // AST there isn't another way to differentiate
                                // between Option and other types...
                                if last.ident.to_string() == "Option" {
                                    match &last.arguments {
                                        PathArguments::AngleBracketed(inner_ty) => {
                                            if inner_ty.args.len() != 1 {
                                                panic!("Found unrecognized Option type with multiple generic type arguments");
                                            }
                                            match inner_ty.args.last().unwrap() {
                                            GenericArgument::Type(inner_ty) => return handle_optional_argument(name, &inner_ty),
                                            _ => panic!("Found unrecognized Option generic type parameter"),
                                        }
                                        }
                                        _ => panic!("Found unrecognized, non-generic Option type"),
                                    }
                                }
                            }
                            handle_required_argument(name, &ty)
                        }
                        _ => panic!("Invalid command callback parameter type"),
                    }
                }
                _ => panic!("Command callback function takes an unhandled argument type."),
            }
        }
    }
}
fn handle_argument ( arg : & FnArg ) -> ( TokenStream , Expr ) { match arg { FnArg :: Receiver ( _ ) => panic ! ( " " ) , FnArg :: Typed ( pattern_type ) => { match & * pattern_type . pat { Pat :: Ident ( ident ) => { let ty = & pattern_type . ty ; let name = & ident . ident ; match & * * ty { Type :: Reference ( r ) => match r . elem . as_ref ( ) { Type :: Slice ( s ) => handle_slice_argument ( name , s ) , _ => panic ! ( " " ) , } , Type :: Path ( p ) => { if let Some ( last ) = p . path . segments . last ( ) { // This is gross, but since we're dealing with an // AST there isn't another way to differentiate // between Option and other types... if last . ident . to_string ( ) == " " { match & last . arguments { PathArguments :: AngleBracketed ( inner_ty ) => { if inner_ty . args . len ( ) != 1 { panic ! ( " " ) ; } match inner_ty . args . last ( ) . unwrap ( ) { GenericArgument :: Type ( inner_ty ) => return handle_optional_argument ( name , & inner_ty ) , _ => panic ! ( " " ) , } } _ => panic ! ( " " ) , } } } handle_required_argument ( name , & ty ) } _ => panic ! ( " " ) , } } _ => panic ! ( " " ) , } } } }
Handles a single callback function argument by generating the code for two
pieces (returned separately in a tuple):
Handles a single callback function argument by generating the code for two pieces ( returned separately in a tuple ) :
arg
&FnArg
arg
&FnArg