ilmoi
ilmoi

Reputation: 2534

Rust: print the name of the function passed in as argument

I'm trying to print out the args to the following function:

pub async fn loop_until_hit_rate_limit<'a, T, Fut>(
    object_arr: &'a [T],
    settings: &'a Settings,
    pool: &'a PgPool,
    f: impl Fn(&'a Settings, &'a PgPool, &'a T) -> Fut + Copy,
    rate_limit: usize,
) where
    Fut: Future<Output = anyhow::Result<()>>,
{
    // do stuff
    println!("args were: {}, {}, {}, {}, {}", object_arr, settings, pool, f, rate_limit) // <--- how do I make this work?
}

The naive approach fails with either this error (for {}):

 ^ `impl Fn(&'a Settings, &'a PgPool, &'a T) -> Fut + Copy` cannot be formatted with the default formatter

Or this error (for {:?}):

^ `impl Fn(&'a Settings, &'a PgPool, &'a T) -> Fut + Copy` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`

Both of which make sense, but I'm not sure how to get around them. I found this thread but it only prints the name of the calling function, not one passed in as arg.

Is there a way to do this?

Upvotes: 3

Views: 1510

Answers (1)

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382160

Is there a way to do this?

Yes. You can get the name of any type with std::any::type_name.

So you can do this:

pub async fn loop_until_hit_rate_limit<'a, T, Fut>(
    object_arr: &'a [T],
    settings: &'a Settings,
    pool: &'a PgPool,
    f: impl Fn(&'a Settings, &'a PgPool, &'a T) -> Fut + Copy,
    rate_limit: usize,
) where
    Fut: Future<Output = anyhow::Result<()>>,
{
    // do stuff
    fn type_name_of<T>(_: T) -> &'static str {
        std::any::type_name::<T>()
    }
    let f_name = type_name_of(f);
    println!("args were: {}, {}, {}, {}, {}", object_arr, settings, pool, f_name, rate_limit)
}

simplified example in playground with various kinds of functions

Upvotes: 6

Related Questions