Repository: tokio-rs/axum
File: axum-macros/src/debug_handler.rs (Rust)

Code before:
    }
    //Amount of IntoRequestParts
    let mut parts_amount: i8 = 0;

    let token_stream = WithPosition::new(elements.iter())
        .enumerate()
        .map(|(_idx, arg)| match &arg {
            //First element type in the tuple
            Position::First(ty) => {
                let typename = extract_clean_typename(ty);
                if typename.is_none() {
                    quote! {}
                } else {
                    let typename = typename.unwrap();
                    match &*typename.to_string() {
                        "Parts" => quote! {},
                        "Response" => quote! {},
                        "StatusCode" => {
                            quote! {}
                        }
                        _ => {
                            parts_amount += 1;
                            check_into_response_parts(ty, parts_amount)
                        }
                    }
                }
            }
            Position::Last(ty) => check_into_response(ty),
            Position::Middle(ty) => {
                parts_amount += 1;
                if parts_amount > 16 {
                    let error_message = format!("Output Tuple cannot have more than 16 arguments.");
                    let error = syn::Error::new_spanned(&item_fn.sig.output, error_message)
                        .to_compile_error();
                    error
                } else {
                    let name = _check_into_response_not_parts(ty);
                    match name {
                        Some(_) => {
                            quote_spanned!{ty.span()=>
                                compile_error!("This type only implements IntoResponse but not IntoResponseParts, try moving it to the last element");
                            }
                        },
                        None => check_into_response_parts(ty, parts_amount)
                    }
                }
            }
            _ => quote! {},
        })
        .collect::<TokenStream>();
    Some(token_stream)

Review comment (refactor):
I think you can do `let typename = extract_clean_typename(ty).map(...)` instead.

Code after:
        )
        .to_compile_error(),
        _ => WithPosition::new(elems)
            .enumerate()
            .map(|(idx, arg)| match arg {
                Position::First(ty) => match extract_clean_typename(ty).as_deref() {
                    Some("StatusCode" | "Response") => quote! {},
                    Some("Parts") => check_is_response_parts(ty, handler_ident, idx),
                    Some(_) | None => {
                        if let Some(tn) = well_known_last_response_type(ty) {
                            syn::Error::new_spanned(
                                ty,
                                format!(
                                    "`{tn}` must be the last element \
                                    in a response tuple"
                                ),
                            )
                            .to_compile_error()
                        } else {
                            check_into_response_parts(ty, handler_ident, idx)
                        }
                    }
                },
                Position::Middle(ty) => {
                    if let Some(tn) = well_known_last_response_type(ty) {
                        syn::Error::new_spanned(
                            ty,
                            format!("`{tn}` must be the last element in a response tuple"),
                        )
                        .to_compile_error()
                    } else {
                        check_into_response_parts(ty, handler_ident, idx)
                    }
                }
                Position::Last(ty) | Position::Only(ty) => check_into_response(handler_ident, ty),
            })
            .collect::<TokenStream>(),
    }
}

fn check_into_response(handler: &Ident, ty: &Type) -> TokenStream {
    let (span, ty) = (ty.span(), ty.clone());

    let check_fn = format_ident!(
        "__axum_macros_check_{handler}_into_response_check",
        span = span,
    );

    let call_check_fn = format_ident!(
        "__axum_macros_check_{handler}_into_response_call_check",
        span = span,