Use macros to implement functions with generics: bounds on associated types do not belong here

How do I use macros to implement functions with generics?

just like Pseudo code

macro_rules! create_fn {
    ($fn_name:ident< $($gkey:ty:$gtype:ty $(,)?)* > ($($param_key:ident:$param_type:tt $(,)?)*)) => {
        pub async fn $fn_name< $($gkey:$gtype)* > ($($param_key:$param_type,)*)

        {
             println!("hello");
        }
    };
}

//this is object code generated by the macro, here handwritten
pub async fn xxx<V: serde::Serialize>(arg: V) {
    println!("hello");
}

fn main() {
    create_fn!(test<V: serde::Serialize>(arg: V));
}


this is run after

error: bounds on associated types do not belong here
  --> example/src/main.rs:3:34
   |
3  |         pub async fn $fn_name< $($gkey:$gtype)* > ($($param_key:$param_type,)*)
   |                                  ^^^^^^ belongs in `where` clause
...
17 |     create_fn!(test<V: serde::Serialize>(arg: V));
   |     --------------------------------------------- in this macro invocation
   |
   = note: this error originates in the macro `create_fn` (in Nightly builds, run with -Z macro-backtrace for more info)


macro_rules! create_fn {
    ($fn_name:ident< $($gkey:ident:$gtype:path $(,)?)* > ($($param_key:ident:$param_type:ty $(,)?)*)) => {
        pub fn $fn_name< $($gkey)* > ($($param_key:$param_type,)*)
        //where V: serde::Serialize
        where $($gkey: $gtype,)*
        {
             println!("hello");
        }
    };
}

//this is object code generated by the macro, here handwritten
pub fn xxx<V: serde::Serialize>(arg: V) {
    println!("hello");
}

fn main() {
    create_fn!(test<V: serde::Serialize>(arg: V));
    test(1);
}