How to create a function that takes different function types?

โš“ Rust    ๐Ÿ“… 2026-03-17    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 2      

surdeus

I have a builder API (kind of like the bon crate), and one of my functions looked like this below. My goal was to create something like a Java/C++ โ€œoverloadโ€, where a single name (fun) was used to give it one of a few different kinds of functions (expressed in the enum).

impl Builder {
    fn fun(mut self, f: impl Into<Fun>) -> Self {
        self.fun = Some(f.into()); self // standard builder pattern
    }
}
enum Fun {
    NoArg(Box<dyn FnOnce() -> () + 'static>),
    CtxArg(Box<dyn FnOnce(&mut Ctx) -> () + 'static>),
}

Problem is I canโ€™t implement From like this:

impl<F> From<F> for Fun where F : FnOnce() -> () + 'static {
    fn from(value: F) -> Self {
        Fun::NoArg(Box::new(value))
    }
}
impl<F> From<F> for Fun where F : FnOnce(&mut Ctx) -> () + 'static {
    fn from(value: F) -> Self {
        Fun::CtxArg(Box::new(value))
    }
}

Error:

error[E0119]: conflicting implementations of trait `From<_>` for type `Fun`
  --> ui/src/run_on_main.rs:43:1
   |
38 | impl<F> From<F> for Fun where F : FnOnce() -> () + 'static {
   | ---------------------------------------------------------- first implementation here
...
43 | impl<F> From<F> for Fun where F : FnOnce(&mut Ctx) -> () + 'static {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Fun`

Is there a way I can write fn fun(โ€ฆ) as described?

Someone on discord suggested the following, but I donโ€™t understand the suggestion. I asked the question here so there is more time and space to discuss.

When implementing the trait, you define an extra generic type for the trait. This type is a marker that specifies which impl to use. When you call the function, rust might be able to infer this extra generic type.

2 posts - 2 participants

Read full topic

๐Ÿท๏ธ Rust_feed